@nascentdigital/funnel-cms 4.6.7 → 5.0.2
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/contentful/ContentfulAccess.d.ts +19 -0
- package/dist/contentful/ContentfulAccess.js +67 -0
- package/dist/contentful/ContentfulApiCommand.d.ts +21 -0
- package/dist/contentful/ContentfulApiCommand.js +20 -0
- package/dist/contentful/ContentfulApiResponse.d.ts +10 -0
- package/dist/contentful/ContentfulApiResponse.js +2 -0
- package/dist/contentful/ContentfulAssetClient.d.ts +11 -0
- package/dist/contentful/ContentfulAssetClient.js +26 -0
- package/dist/contentful/ContentfulAuthClient.d.ts +9 -0
- package/dist/contentful/ContentfulAuthClient.js +20 -0
- package/dist/contentful/ContentfulChangeSetClient.d.ts +14 -0
- package/dist/contentful/ContentfulChangeSetClient.js +35 -0
- package/dist/contentful/ContentfulCollectionClient.d.ts +38 -0
- package/dist/contentful/ContentfulCollectionClient.js +173 -0
- package/dist/contentful/ContentfulContentClient.d.ts +59 -0
- package/dist/contentful/ContentfulContentClient.js +208 -0
- package/dist/contentful/ContentfulContentClientFactory.d.ts +12 -0
- package/dist/contentful/ContentfulContentClientFactory.js +19 -0
- package/dist/contentful/ContentfulPageClient.d.ts +43 -0
- package/dist/contentful/ContentfulPageClient.js +251 -0
- package/dist/contentful/ContentfulSiteConfigClient.d.ts +9 -0
- package/dist/contentful/ContentfulSiteConfigClient.js +33 -0
- package/dist/contentful/ContentfulUpgradeClient.d.ts +9 -0
- package/dist/contentful/ContentfulUpgradeClient.js +17 -0
- package/dist/contentful/ContentfulUserClient.d.ts +13 -0
- package/dist/contentful/ContentfulUserClient.js +32 -0
- package/dist/contentful/IContentfulContentClient.d.ts +52 -0
- package/dist/contentful/IContentfulContentClient.js +2 -0
- package/dist/contentful/api/ContentfulApi.d.ts +10 -0
- package/dist/contentful/api/ContentfulApi.js +82 -0
- package/dist/contentful/index.d.ts +12 -0
- package/dist/contentful/index.js +28 -0
- package/dist/contentful/models/ContentfulAssetData.d.ts +8 -0
- package/dist/contentful/models/ContentfulAssetData.js +29 -0
- package/dist/contentful/models/ContentfulCollectionData.d.ts +11 -0
- package/dist/contentful/models/ContentfulCollectionData.js +98 -0
- package/dist/contentful/models/ContentfulData.d.ts +40 -0
- package/dist/contentful/models/ContentfulData.js +118 -0
- package/dist/contentful/models/ContentfulPageData.d.ts +17 -0
- package/dist/contentful/models/ContentfulPageData.js +117 -0
- package/dist/contentful/models/ContentfulSiteConfigData.d.ts +10 -0
- package/dist/contentful/models/ContentfulSiteConfigData.js +9 -0
- package/dist/contentful/models/ContentfulUserData.d.ts +6 -0
- package/dist/contentful/models/ContentfulUserData.js +26 -0
- package/dist/contentful/models/index.d.ts +6 -0
- package/dist/contentful/models/index.js +22 -0
- package/dist/contentful/server.d.ts +1 -0
- package/dist/contentful/server.js +17 -0
- package/package.json +9 -3
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.ContentfulContentClient = void 0;
|
|
15
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
16
|
+
const contentful_management_1 = require("contentful-management");
|
|
17
|
+
const models_1 = require("../models");
|
|
18
|
+
const ContentfulAccess_1 = require("./ContentfulAccess");
|
|
19
|
+
const ContentfulAssetClient_1 = require("./ContentfulAssetClient");
|
|
20
|
+
const ContentfulAuthClient_1 = require("./ContentfulAuthClient");
|
|
21
|
+
const ContentfulChangeSetClient_1 = require("./ContentfulChangeSetClient");
|
|
22
|
+
const ContentfulCollectionClient_1 = require("./ContentfulCollectionClient");
|
|
23
|
+
const ContentfulPageClient_1 = require("./ContentfulPageClient");
|
|
24
|
+
const ContentfulSiteConfigClient_1 = require("./ContentfulSiteConfigClient");
|
|
25
|
+
const ContentfulUpgradeClient_1 = require("./ContentfulUpgradeClient");
|
|
26
|
+
const ContentfulUserClient_1 = require("./ContentfulUserClient");
|
|
27
|
+
const models_2 = require("./models");
|
|
28
|
+
// class
|
|
29
|
+
class ContentfulContentClient {
|
|
30
|
+
constructor(args) {
|
|
31
|
+
var _a;
|
|
32
|
+
// initialize instance variables
|
|
33
|
+
let sp;
|
|
34
|
+
if (ContentfulContentClient.ConstructorArgs.isForServer(args)) {
|
|
35
|
+
this.user = models_1.User.UNAUTHENTICATED;
|
|
36
|
+
this.locale = args.locale;
|
|
37
|
+
const options = { defaults: { spaceId: args.spaceId, environmentId: args.environment } };
|
|
38
|
+
this.cma = (0, contentful_management_1.createClient)({ accessToken: args.accessToken }, options);
|
|
39
|
+
this.cda = (0, contentful_management_1.createClient)({ accessToken: args.deliveryAccessToken, host: 'cdn.contentful.com' }, options);
|
|
40
|
+
this.cpa = (0, contentful_management_1.createClient)({ accessToken: args.previewAccessToken, host: 'preview.contentful.com' }, options);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const { user, locales, cma, ids } = args.sdk;
|
|
44
|
+
this.user = new models_1.User({
|
|
45
|
+
brands: [funnel_core_1.AppConfig.brand()],
|
|
46
|
+
id: user.sys.id,
|
|
47
|
+
email: user.email,
|
|
48
|
+
username: user.email,
|
|
49
|
+
blocked: false,
|
|
50
|
+
role: user.spaceMembership.roles.length === 0
|
|
51
|
+
? 'public'
|
|
52
|
+
: user.spaceMembership.roles
|
|
53
|
+
.map(({ name }) => models_2.ContentfulUserData.parseRole(name))
|
|
54
|
+
.sort((lhs, rhs) => lhs.compareTo(rhs))[0].id
|
|
55
|
+
});
|
|
56
|
+
this.locale = locales.default;
|
|
57
|
+
this.cma = cma;
|
|
58
|
+
const options = { defaults: { spaceId: ids.space, environmentId: (_a = ids.environmentAlias) !== null && _a !== void 0 ? _a : ids.environment } };
|
|
59
|
+
this.cda = (0, contentful_management_1.createClient)({ accessToken: args.deliveryAccessToken, host: 'cdn.contentful.com' }, options);
|
|
60
|
+
this.cpa = (0, contentful_management_1.createClient)({ accessToken: args.previewAccessToken, host: 'preview.contentful.com' }, options);
|
|
61
|
+
}
|
|
62
|
+
this.deliveryAccessToken = args.deliveryAccessToken;
|
|
63
|
+
this.previewAccessToken = args.previewAccessToken;
|
|
64
|
+
this.auth = new ContentfulAuthClient_1.ContentfulAuthClient(this);
|
|
65
|
+
this.changeSets = new ContentfulChangeSetClient_1.ContentfulChangeSetClient(this);
|
|
66
|
+
this.files = new ContentfulAssetClient_1.ContentfulAssetClient(this);
|
|
67
|
+
this.pages = new ContentfulPageClient_1.ContentfulPageClient(this);
|
|
68
|
+
this.collections = new ContentfulCollectionClient_1.ContentfulCollectionClient(this);
|
|
69
|
+
this.upgrade = new ContentfulUpgradeClient_1.ContentfulUpgradeClient(this);
|
|
70
|
+
this.users = new ContentfulUserClient_1.ContentfulUserClient(this);
|
|
71
|
+
this.siteConfig = new ContentfulSiteConfigClient_1.ContentfulSiteConfigClient(this);
|
|
72
|
+
}
|
|
73
|
+
get token() {
|
|
74
|
+
throw new funnel_core_1.NotImplementedError();
|
|
75
|
+
}
|
|
76
|
+
set token(token) {
|
|
77
|
+
throw new funnel_core_1.NotImplementedError();
|
|
78
|
+
}
|
|
79
|
+
clearToken() {
|
|
80
|
+
throw new funnel_core_1.NotImplementedError();
|
|
81
|
+
}
|
|
82
|
+
async createEntry(contentTypeId, entry) {
|
|
83
|
+
// create entry
|
|
84
|
+
const { locale, cma } = this;
|
|
85
|
+
const data = await cma.entry.create({ contentTypeId }, {
|
|
86
|
+
fields: models_2.ContentfulData.toEntryData(entry, locale)
|
|
87
|
+
});
|
|
88
|
+
// transform + return new entry
|
|
89
|
+
return models_2.ContentfulData.fromCmaData(data, locale);
|
|
90
|
+
}
|
|
91
|
+
async getEntry({ entryId, includeLinks = false, version = 'draft' }) {
|
|
92
|
+
var _a, _b;
|
|
93
|
+
// get entry
|
|
94
|
+
const client = version === 'published' ? this.cda : this.cpa;
|
|
95
|
+
const result = await client.entry.getMany({
|
|
96
|
+
query: {
|
|
97
|
+
'sys.id': entryId,
|
|
98
|
+
include: includeLinks === true
|
|
99
|
+
? 10
|
|
100
|
+
: includeLinks || undefined
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const { items: [item], includes } = result;
|
|
104
|
+
console.debug('[ContentfulContentClient/getEntry] fetched', result);
|
|
105
|
+
// bind references
|
|
106
|
+
const entry = models_2.ContentfulData.fromCdaData(item);
|
|
107
|
+
const references = (_b = (_a = includes === null || includes === void 0 ? void 0 : includes.Entry) === null || _a === void 0 ? void 0 : _a.map(link => models_2.ContentfulData.fromCdaData(link))) !== null && _b !== void 0 ? _b : [];
|
|
108
|
+
// return normalized item
|
|
109
|
+
return { entry, references };
|
|
110
|
+
}
|
|
111
|
+
async getEntries(_a) {
|
|
112
|
+
var _b, _c;
|
|
113
|
+
var { limit = 1000, version = 'draft', includeLinks = false } = _a, query = __rest(_a, ["limit", "version", "includeLinks"]);
|
|
114
|
+
// loop until no more pages
|
|
115
|
+
const client = version === 'published' ? this.cda : this.cpa;
|
|
116
|
+
let skip = 0;
|
|
117
|
+
let total = 1;
|
|
118
|
+
const entries = [];
|
|
119
|
+
const includes = [];
|
|
120
|
+
while (skip < total) {
|
|
121
|
+
// fetch next page
|
|
122
|
+
const _d = await client.entry.getMany({
|
|
123
|
+
query: Object.assign(Object.assign({}, query), { limit,
|
|
124
|
+
skip, include: includeLinks === true
|
|
125
|
+
? 10
|
|
126
|
+
: includeLinks || undefined })
|
|
127
|
+
}), { items } = _d, response = __rest(_d, ["items"]);
|
|
128
|
+
console.debug('[ContentfulContentClient/getEntries] fetched page', { query, items, response });
|
|
129
|
+
// add items
|
|
130
|
+
items.forEach(item => entries.push(models_2.ContentfulData.fromCdaData(item)));
|
|
131
|
+
includes.push(...((_c = (_b = response.includes) === null || _b === void 0 ? void 0 : _b.Entry) !== null && _c !== void 0 ? _c : []));
|
|
132
|
+
// update counts
|
|
133
|
+
total = response.total;
|
|
134
|
+
skip += limit;
|
|
135
|
+
}
|
|
136
|
+
console.debug('[ContentfulContentClient/getEntries] fetched entries', { entries, includes });
|
|
137
|
+
// normalize references
|
|
138
|
+
const references = includes.map(link => models_2.ContentfulData.fromCdaData(link));
|
|
139
|
+
// return
|
|
140
|
+
return {
|
|
141
|
+
entries,
|
|
142
|
+
references
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
static async forEditor(sdk) {
|
|
146
|
+
var _a;
|
|
147
|
+
// get current site config (throw if we can't)
|
|
148
|
+
const { user, cma, locales: { default: locale } } = sdk;
|
|
149
|
+
const userId = user.sys.id;
|
|
150
|
+
const brand = funnel_core_1.AppConfig.brand();
|
|
151
|
+
const { items: [siteConfigData] } = await cma.entry.getMany({
|
|
152
|
+
query: {
|
|
153
|
+
content_type: models_2.ContentfulSiteConfigData.contentType,
|
|
154
|
+
'fields.brand': brand
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
const siteConfig = siteConfigData && models_2.ContentfulData.fromCmaData(siteConfigData, locale);
|
|
158
|
+
if (!siteConfig) {
|
|
159
|
+
throw new funnel_core_1.NotFoundError('Unable to resolve SiteConfig');
|
|
160
|
+
}
|
|
161
|
+
// grant user temp access via the new token
|
|
162
|
+
const access = ContentfulAccess_1.ContentfulAccess.new(userId);
|
|
163
|
+
await cma.entry.patch({ entryId: siteConfig.id, version: siteConfig.__version }, [
|
|
164
|
+
{
|
|
165
|
+
op: 'replace',
|
|
166
|
+
path: `/fields/access/${locale}`,
|
|
167
|
+
value: Object.assign(Object.assign({}, siteConfig.access), { [userId]: access.data })
|
|
168
|
+
}
|
|
169
|
+
]);
|
|
170
|
+
// call API to get delivery/preview tokens
|
|
171
|
+
const command = {
|
|
172
|
+
type: 'GetAccessTokens',
|
|
173
|
+
userId: access.userId,
|
|
174
|
+
token: access.token
|
|
175
|
+
};
|
|
176
|
+
const response = await fetch('/api/contentful', {
|
|
177
|
+
method: 'POST',
|
|
178
|
+
body: JSON.stringify(command)
|
|
179
|
+
});
|
|
180
|
+
// throw if response failed
|
|
181
|
+
await funnel_core_1.IsometricErrorUtils.checkResponse(response);
|
|
182
|
+
// throw if not valid
|
|
183
|
+
const { data } = (_a = await response.json()) !== null && _a !== void 0 ? _a : {};
|
|
184
|
+
const { deliveryAccessToken, previewAccessToken } = data !== null && data !== void 0 ? data : {};
|
|
185
|
+
if (!deliveryAccessToken || !previewAccessToken) {
|
|
186
|
+
throw new funnel_core_1.IllegalStateError('Invalid data return from API');
|
|
187
|
+
}
|
|
188
|
+
console.debug('[ContentfulContentClient/forEditor] creating with', { sdk, deliveryAccessToken, previewAccessToken });
|
|
189
|
+
// create + return new client
|
|
190
|
+
return new ContentfulContentClient({ sdk, deliveryAccessToken, previewAccessToken });
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
exports.ContentfulContentClient = ContentfulContentClient;
|
|
194
|
+
// extension
|
|
195
|
+
(function (ContentfulContentClient) {
|
|
196
|
+
let ConstructorArgs;
|
|
197
|
+
(function (ConstructorArgs) {
|
|
198
|
+
// helpers
|
|
199
|
+
function isForServer(args) {
|
|
200
|
+
return 'accessToken' in args;
|
|
201
|
+
}
|
|
202
|
+
ConstructorArgs.isForServer = isForServer;
|
|
203
|
+
function isForEditor(args) {
|
|
204
|
+
return 'sdk' in args;
|
|
205
|
+
}
|
|
206
|
+
ConstructorArgs.isForEditor = isForEditor;
|
|
207
|
+
})(ConstructorArgs = ContentfulContentClient.ConstructorArgs || (ContentfulContentClient.ConstructorArgs = {}));
|
|
208
|
+
})(ContentfulContentClient || (exports.ContentfulContentClient = ContentfulContentClient = {}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ContentClient } from '../api';
|
|
2
|
+
import { ContentfulContentClient } from './ContentfulContentClient';
|
|
3
|
+
export declare class ContentfulContentClientFactory implements ContentClient.Factory {
|
|
4
|
+
private readonly args;
|
|
5
|
+
private readonly _serverClient;
|
|
6
|
+
constructor(args: ContentfulContentClientFactory.ConstructorArgs);
|
|
7
|
+
forServer(): ContentfulContentClient;
|
|
8
|
+
forEditor(): ContentfulContentClient;
|
|
9
|
+
}
|
|
10
|
+
export declare namespace ContentfulContentClientFactory {
|
|
11
|
+
type ConstructorArgs = ContentfulContentClient.ConstructorArgs;
|
|
12
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentfulContentClientFactory = void 0;
|
|
4
|
+
const ContentfulContentClient_1 = require("./ContentfulContentClient");
|
|
5
|
+
// factory
|
|
6
|
+
class ContentfulContentClientFactory {
|
|
7
|
+
constructor(args) {
|
|
8
|
+
this.args = args;
|
|
9
|
+
// initialize instance variables
|
|
10
|
+
this._serverClient = new ContentfulContentClient_1.ContentfulContentClient(args);
|
|
11
|
+
}
|
|
12
|
+
forServer() {
|
|
13
|
+
return this._serverClient;
|
|
14
|
+
}
|
|
15
|
+
forEditor() {
|
|
16
|
+
return new ContentfulContentClient_1.ContentfulContentClient(this.args);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.ContentfulContentClientFactory = ContentfulContentClientFactory;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Schema } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { PageClient } from '../api';
|
|
3
|
+
import { IContentfulContentClient } from './IContentfulContentClient';
|
|
4
|
+
import { ContentfulPageData } from './models';
|
|
5
|
+
export declare class ContentfulPageClient implements PageClient {
|
|
6
|
+
readonly cms: IContentfulContentClient;
|
|
7
|
+
constructor(cms: IContentfulContentClient);
|
|
8
|
+
getOverview(args: PageClient.GetOverview.Args): Promise<PageClient.GetOverview.Result>;
|
|
9
|
+
getSummaries(args: PageClient.GetSummaries.Args): Promise<PageClient.GetSummaries.Result>;
|
|
10
|
+
getPreviews(args: PageClient.GetPreviews.Args): Promise<PageClient.GetPreviews.Result>;
|
|
11
|
+
search(args: PageClient.Search.Args): Promise<PageClient.Search.Result>;
|
|
12
|
+
query(args: PageClient.Query.Args): Promise<PageClient.Query.Result>;
|
|
13
|
+
find(args: PageClient.Find.Args): Promise<PageClient.Find.Result>;
|
|
14
|
+
getGroup(args: PageClient.GetGroup.Args): Promise<ContentfulPageClient.GetGroup.Result>;
|
|
15
|
+
get(args: PageClient.Get.Args): Promise<ContentfulPageClient.Get.Result>;
|
|
16
|
+
create(args: PageClient.Create.Args): Promise<PageClient.Create.Result>;
|
|
17
|
+
duplicate(args: PageClient.Duplicate.Args): Promise<PageClient.Duplicate.Result>;
|
|
18
|
+
update(args: PageClient.Update.Args): Promise<ContentfulPageClient.Update.Result>;
|
|
19
|
+
replace(args: PageClient.Replace.Args): Promise<PageClient.Replace.Result>;
|
|
20
|
+
touch(args: PageClient.Touch.Args): Promise<PageClient.Touch.Result>;
|
|
21
|
+
unpublish(args: PageClient.Unpublish.Args): Promise<PageClient.Unpublish.Result>;
|
|
22
|
+
getDependants(args: PageClient.GetDependants.Args): Promise<PageClient.GetDependants.Result>;
|
|
23
|
+
getDependencies(args: PageClient.GetDependencies.Args): Promise<PageClient.GetDependencies.Result>;
|
|
24
|
+
validateSlug(args: PageClient.ValidateSlug.Args): Promise<PageClient.ValidateSlug.Result>;
|
|
25
|
+
}
|
|
26
|
+
export declare namespace ContentfulPageClient {
|
|
27
|
+
type FlattedPageData = Omit<Schema.Page.FlattenedData, 'data'> & {
|
|
28
|
+
data: ContentfulPageData.ForSchema;
|
|
29
|
+
};
|
|
30
|
+
namespace GetGroup {
|
|
31
|
+
type Result = Omit<PageClient.GetGroup.Result, 'page'> & {
|
|
32
|
+
page?: FlattedPageData;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
namespace Get {
|
|
36
|
+
type Result = FlattedPageData | undefined;
|
|
37
|
+
}
|
|
38
|
+
namespace Update {
|
|
39
|
+
type Result = Omit<PageClient.Update.Result, 'page'> & {
|
|
40
|
+
page?: FlattedPageData;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentfulPageClient = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
const models_1 = require("./models");
|
|
6
|
+
// class
|
|
7
|
+
class ContentfulPageClient {
|
|
8
|
+
constructor(cms) {
|
|
9
|
+
this.cms = cms;
|
|
10
|
+
}
|
|
11
|
+
async getOverview(args) {
|
|
12
|
+
// fetch all pages
|
|
13
|
+
const { cms } = this;
|
|
14
|
+
const { entries } = await cms.getEntries(Object.assign({ content_type: models_1.ContentfulPageData.contentType, version: args.version, select: getPageSelect(funnel_core_1.Schema.Page.Data.AsLink.props) }, getPageQueryParams(args)));
|
|
15
|
+
// convert entries to page data
|
|
16
|
+
const pagesData = entries.map(entry => models_1.ContentfulPageData.deserialize(entry, funnel_core_1.Schema.Page.Data.AsLink.props));
|
|
17
|
+
// setup maps
|
|
18
|
+
const staticPages = new Map();
|
|
19
|
+
const dynamicPages = new Map();
|
|
20
|
+
// go over each page data
|
|
21
|
+
for (const data of pagesData) {
|
|
22
|
+
// use appropriate map (determine if page is static/dynamic)
|
|
23
|
+
const pagesMap = data.slug === undefined
|
|
24
|
+
? staticPages
|
|
25
|
+
: dynamicPages;
|
|
26
|
+
// get references by page type
|
|
27
|
+
let refs = pagesMap.get(data.type);
|
|
28
|
+
if (!refs) {
|
|
29
|
+
pagesMap.set(data.type, refs = []);
|
|
30
|
+
}
|
|
31
|
+
// add to refs
|
|
32
|
+
refs.push(data);
|
|
33
|
+
}
|
|
34
|
+
// return
|
|
35
|
+
return {
|
|
36
|
+
// static pages
|
|
37
|
+
static: staticPages.entries().map(([type, refs]) => ({
|
|
38
|
+
type,
|
|
39
|
+
refs: refs.reduce((refs, ref) => {
|
|
40
|
+
// add page
|
|
41
|
+
refs[ref.language] = ref;
|
|
42
|
+
// keep reducing
|
|
43
|
+
return refs;
|
|
44
|
+
}, {})
|
|
45
|
+
})).toArray(),
|
|
46
|
+
// dynamic pages
|
|
47
|
+
dynamic: dynamicPages.entries().map(([type, refs]) => ({
|
|
48
|
+
type,
|
|
49
|
+
count: refs.length
|
|
50
|
+
})).toArray()
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async getSummaries(args) {
|
|
54
|
+
// fetch items (bail if there are no instances
|
|
55
|
+
const { cms } = this;
|
|
56
|
+
const { entries } = await cms.getEntries(Object.assign({ content_type: models_1.ContentfulPageData.contentType, version: args.version, select: getPageSelect(funnel_core_1.Schema.Page.Data.AsLink.props) }, getPageQueryParams(args)));
|
|
57
|
+
// return result
|
|
58
|
+
return entries.map(entry => models_1.ContentfulPageData.deserialize(entry, funnel_core_1.Schema.Page.Data.AsLink.props));
|
|
59
|
+
}
|
|
60
|
+
getPreviews(args) {
|
|
61
|
+
throw new funnel_core_1.NotImplementedError();
|
|
62
|
+
}
|
|
63
|
+
search(args) {
|
|
64
|
+
throw new funnel_core_1.NotImplementedError();
|
|
65
|
+
}
|
|
66
|
+
query(args) {
|
|
67
|
+
throw new funnel_core_1.NotImplementedError();
|
|
68
|
+
}
|
|
69
|
+
find(args) {
|
|
70
|
+
throw new funnel_core_1.NotImplementedError();
|
|
71
|
+
}
|
|
72
|
+
async getGroup(args) {
|
|
73
|
+
// fetch items (bail if there are no instances
|
|
74
|
+
const { cms } = this;
|
|
75
|
+
const { entries } = await cms.getEntries(Object.assign({ content_type: models_1.ContentfulPageData.contentType, version: args.version, select: getPageSelect(funnel_core_1.Schema.Page.Data.AsGroup.Instance.props) }, getPageQueryParams(args)));
|
|
76
|
+
// bail if no items
|
|
77
|
+
if (entries.length === 0) {
|
|
78
|
+
console.debug('[ContentfulPageClient/getGroup] no items in group', args);
|
|
79
|
+
const { brand, groupId: possibleGroupId, type, slug, region } = args;
|
|
80
|
+
return {
|
|
81
|
+
group: { groupId: possibleGroupId !== null && possibleGroupId !== void 0 ? possibleGroupId : funnel_core_1.Schema.Page.GroupId.empty, brand, type, slug, region, instances: [] }
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
console.debug('[ContentfulPageClient/getGroup] processing group items', { args, entries });
|
|
85
|
+
// collate the group ids into summaries (fetches full page if region/language match exists
|
|
86
|
+
const instances = entries.map(entry => models_1.ContentfulPageData.deserialize(entry, funnel_core_1.Schema.Page.Data.AsGroup.Instance.props));
|
|
87
|
+
// bind page (if it exists)
|
|
88
|
+
const { language, version } = args;
|
|
89
|
+
const pageInstance = instances
|
|
90
|
+
.find(instance => instance.language === language);
|
|
91
|
+
console.debug('[ContentfulPageClient/getGroup] getting page using this.get...', { id: pageInstance === null || pageInstance === void 0 ? void 0 : pageInstance.id, version });
|
|
92
|
+
const page = pageInstance
|
|
93
|
+
? await this.get({ id: pageInstance.id, version })
|
|
94
|
+
: undefined;
|
|
95
|
+
// return group (and optional page)
|
|
96
|
+
const { type, brand, groupId, region, slug } = entries[0];
|
|
97
|
+
return {
|
|
98
|
+
group: {
|
|
99
|
+
groupId,
|
|
100
|
+
type,
|
|
101
|
+
brand,
|
|
102
|
+
region,
|
|
103
|
+
slug,
|
|
104
|
+
instances
|
|
105
|
+
},
|
|
106
|
+
page
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async get(args) {
|
|
110
|
+
// create args for query
|
|
111
|
+
const queryArgs = 'id' in args
|
|
112
|
+
? { ids: [args.id], version: args.version }
|
|
113
|
+
: args;
|
|
114
|
+
// fetch entries (should be one entry)
|
|
115
|
+
const { cms } = this;
|
|
116
|
+
const { entries, references } = await cms.getEntries(Object.assign({ content_type: models_1.ContentfulPageData.contentType, includeLinks: true, version: args.version, limit: 1 }, getPageQueryParams(queryArgs)));
|
|
117
|
+
// skip if no entries
|
|
118
|
+
if (entries.length === 0) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
// use first entry and deserialize
|
|
122
|
+
return Object.assign({ data: models_1.ContentfulPageData.deserialize(entries[0]) }, models_1.ContentfulPageData.deserializeRefs(references));
|
|
123
|
+
}
|
|
124
|
+
create(args) {
|
|
125
|
+
throw new funnel_core_1.NotImplementedError();
|
|
126
|
+
}
|
|
127
|
+
duplicate(args) {
|
|
128
|
+
throw new funnel_core_1.NotImplementedError();
|
|
129
|
+
}
|
|
130
|
+
update(args) {
|
|
131
|
+
throw new funnel_core_1.NotImplementedError();
|
|
132
|
+
}
|
|
133
|
+
replace(args) {
|
|
134
|
+
throw new funnel_core_1.NotImplementedError();
|
|
135
|
+
}
|
|
136
|
+
touch(args) {
|
|
137
|
+
throw new funnel_core_1.NotImplementedError();
|
|
138
|
+
}
|
|
139
|
+
unpublish(args) {
|
|
140
|
+
throw new funnel_core_1.NotImplementedError();
|
|
141
|
+
}
|
|
142
|
+
getDependants(args) {
|
|
143
|
+
throw new funnel_core_1.NotImplementedError();
|
|
144
|
+
}
|
|
145
|
+
getDependencies(args) {
|
|
146
|
+
throw new funnel_core_1.NotImplementedError();
|
|
147
|
+
}
|
|
148
|
+
validateSlug(args) {
|
|
149
|
+
throw new funnel_core_1.NotImplementedError();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
exports.ContentfulPageClient = ContentfulPageClient;
|
|
153
|
+
// helpers
|
|
154
|
+
function getPageQueryParams(query) {
|
|
155
|
+
// build filters
|
|
156
|
+
const { ids = [], groupId, brand, type, slug, region, language, name, tags = [], tagsMatch = 'any', version } = query;
|
|
157
|
+
const filters = {};
|
|
158
|
+
// filter id(s)
|
|
159
|
+
if (ids.length === 1) {
|
|
160
|
+
filters['sys.id'] = ids[0];
|
|
161
|
+
}
|
|
162
|
+
else if (ids.length > 1) {
|
|
163
|
+
filters['sys.id[in]'] = ids.join(',');
|
|
164
|
+
}
|
|
165
|
+
// filter group
|
|
166
|
+
if (groupId) {
|
|
167
|
+
filters['fields.groupId'] = groupId;
|
|
168
|
+
}
|
|
169
|
+
// filter brand
|
|
170
|
+
if (brand) {
|
|
171
|
+
filters['fields.brand'] = brand;
|
|
172
|
+
}
|
|
173
|
+
// filter type(s)
|
|
174
|
+
const normalizedType = type
|
|
175
|
+
? Array.isArray(type)
|
|
176
|
+
? type
|
|
177
|
+
: [type]
|
|
178
|
+
: [];
|
|
179
|
+
if (normalizedType.length === 1) {
|
|
180
|
+
filters['fields.type'] = normalizedType[0];
|
|
181
|
+
}
|
|
182
|
+
else if (normalizedType.length > 1) {
|
|
183
|
+
filters['fields.type[in]'] = normalizedType.join(',');
|
|
184
|
+
}
|
|
185
|
+
// filter slug
|
|
186
|
+
if (slug) {
|
|
187
|
+
filters['fields.slug'] = slug;
|
|
188
|
+
}
|
|
189
|
+
// filter region
|
|
190
|
+
if (region) {
|
|
191
|
+
filters['fields.region'] = region;
|
|
192
|
+
}
|
|
193
|
+
// filter language
|
|
194
|
+
if (language) {
|
|
195
|
+
filters['fields.language'] = language;
|
|
196
|
+
}
|
|
197
|
+
// filter name
|
|
198
|
+
if (name) {
|
|
199
|
+
filters['fields.name[match]'] = name;
|
|
200
|
+
}
|
|
201
|
+
// filter tags
|
|
202
|
+
if (tags.length > 0) {
|
|
203
|
+
filters[`fields.tags[${tagsMatch === 'any' ? 'in' : 'all'}]`] = tags
|
|
204
|
+
.filter((tag) => !!tag)
|
|
205
|
+
.join(',');
|
|
206
|
+
}
|
|
207
|
+
// return filters
|
|
208
|
+
return filters;
|
|
209
|
+
}
|
|
210
|
+
function getPageSelect(props) {
|
|
211
|
+
// build select
|
|
212
|
+
const select = new Set(['sys']);
|
|
213
|
+
for (const prop of props) {
|
|
214
|
+
switch (prop) {
|
|
215
|
+
// parity
|
|
216
|
+
case 'groupId':
|
|
217
|
+
case 'brand':
|
|
218
|
+
case 'type':
|
|
219
|
+
case 'slug':
|
|
220
|
+
case 'url':
|
|
221
|
+
case 'region':
|
|
222
|
+
case 'language':
|
|
223
|
+
case 'name':
|
|
224
|
+
case 'tags':
|
|
225
|
+
case 'discover':
|
|
226
|
+
case 'preview':
|
|
227
|
+
case 'content':
|
|
228
|
+
case 'state':
|
|
229
|
+
case 'errors':
|
|
230
|
+
case 'publishedOn':
|
|
231
|
+
case 'publication':
|
|
232
|
+
select.add(`fields.${prop}`);
|
|
233
|
+
break;
|
|
234
|
+
// links
|
|
235
|
+
case 'files':
|
|
236
|
+
case 'pages':
|
|
237
|
+
case 'collections':
|
|
238
|
+
select.add('fields.references');
|
|
239
|
+
break;
|
|
240
|
+
// ignore the rest
|
|
241
|
+
default:
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// bail if nothing added
|
|
246
|
+
if (select.size === 0) {
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
// return as joint string
|
|
250
|
+
return Array.from(select).join(',');
|
|
251
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SiteConfigClient } from '../api';
|
|
2
|
+
import { IContentfulContentClient } from './IContentfulContentClient';
|
|
3
|
+
import { ContentfulSiteConfigData } from './models';
|
|
4
|
+
export declare class ContentfulSiteConfigClient implements SiteConfigClient {
|
|
5
|
+
readonly cms: IContentfulContentClient;
|
|
6
|
+
constructor(cms: IContentfulContentClient);
|
|
7
|
+
get({ brand }: SiteConfigClient.Get.Args): Promise<ContentfulSiteConfigData>;
|
|
8
|
+
update(args: SiteConfigClient.Update.Args): Promise<SiteConfigClient.Update.Result>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentfulSiteConfigClient = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
const models_1 = require("./models");
|
|
6
|
+
// class
|
|
7
|
+
class ContentfulSiteConfigClient {
|
|
8
|
+
constructor(cms) {
|
|
9
|
+
this.cms = cms;
|
|
10
|
+
}
|
|
11
|
+
async get({ brand }) {
|
|
12
|
+
// fetch config model
|
|
13
|
+
let { entries: [siteConfig] } = await this.cms.getEntries({
|
|
14
|
+
content_type: models_1.ContentfulSiteConfigData.contentType,
|
|
15
|
+
limit: 1,
|
|
16
|
+
'fields.brand': brand
|
|
17
|
+
});
|
|
18
|
+
// or create it if it's not there
|
|
19
|
+
if (!siteConfig) {
|
|
20
|
+
siteConfig = await this.cms.createEntry(models_1.ContentfulSiteConfigData.contentType, {
|
|
21
|
+
brand,
|
|
22
|
+
lockdownEditor: false,
|
|
23
|
+
access: {}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
// return config
|
|
27
|
+
return siteConfig;
|
|
28
|
+
}
|
|
29
|
+
update(args) {
|
|
30
|
+
throw new funnel_core_1.NotImplementedError();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.ContentfulSiteConfigClient = ContentfulSiteConfigClient;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { UpgradeClient } from '../api';
|
|
2
|
+
import { Upgrade } from '../models';
|
|
3
|
+
import { IContentfulContentClient } from './IContentfulContentClient';
|
|
4
|
+
export declare class ContentfulUpgradeClient implements UpgradeClient {
|
|
5
|
+
readonly cms: IContentfulContentClient;
|
|
6
|
+
constructor(cms: IContentfulContentClient);
|
|
7
|
+
status(): Promise<Upgrade.Status>;
|
|
8
|
+
upgrade(): Promise<Upgrade.Status>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentfulUpgradeClient = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
// class
|
|
6
|
+
class ContentfulUpgradeClient {
|
|
7
|
+
constructor(cms) {
|
|
8
|
+
this.cms = cms;
|
|
9
|
+
}
|
|
10
|
+
status() {
|
|
11
|
+
throw new funnel_core_1.NotImplementedError();
|
|
12
|
+
}
|
|
13
|
+
upgrade() {
|
|
14
|
+
throw new funnel_core_1.NotImplementedError();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.ContentfulUpgradeClient = ContentfulUpgradeClient;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { UserClient } from '../api';
|
|
2
|
+
import { IContentfulContentClient } from './IContentfulContentClient';
|
|
3
|
+
export declare class ContentfulUserClient implements UserClient {
|
|
4
|
+
readonly cms: IContentfulContentClient;
|
|
5
|
+
constructor(cms: IContentfulContentClient);
|
|
6
|
+
me(): Promise<UserClient.Me.Result>;
|
|
7
|
+
getUsers(args?: UserClient.GetUsers.Args): Promise<UserClient.GetUsers.Result>;
|
|
8
|
+
getUser(args: UserClient.GetUser.Args): Promise<UserClient.GetUser.Result>;
|
|
9
|
+
createUser(args: UserClient.CreateUser.Args): Promise<UserClient.CreateUser.Result>;
|
|
10
|
+
updateUser(args: UserClient.UpdateUser.Args): Promise<UserClient.UpdateUser.Result>;
|
|
11
|
+
resetUser(args: UserClient.ResetUser.Args): Promise<UserClient.ResetUser.Result>;
|
|
12
|
+
deleteUser(args: UserClient.DeleteUser.Args): Promise<UserClient.DeleteUser.Result>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentfulUserClient = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
// class
|
|
6
|
+
class ContentfulUserClient {
|
|
7
|
+
constructor(cms) {
|
|
8
|
+
this.cms = cms;
|
|
9
|
+
}
|
|
10
|
+
async me() {
|
|
11
|
+
return this.cms.user.data;
|
|
12
|
+
}
|
|
13
|
+
getUsers(args) {
|
|
14
|
+
throw new funnel_core_1.NotImplementedError();
|
|
15
|
+
}
|
|
16
|
+
getUser(args) {
|
|
17
|
+
throw new funnel_core_1.NotImplementedError();
|
|
18
|
+
}
|
|
19
|
+
createUser(args) {
|
|
20
|
+
throw new funnel_core_1.NotImplementedError();
|
|
21
|
+
}
|
|
22
|
+
updateUser(args) {
|
|
23
|
+
throw new funnel_core_1.NotImplementedError();
|
|
24
|
+
}
|
|
25
|
+
resetUser(args) {
|
|
26
|
+
throw new funnel_core_1.NotImplementedError();
|
|
27
|
+
}
|
|
28
|
+
deleteUser(args) {
|
|
29
|
+
throw new funnel_core_1.NotImplementedError();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.ContentfulUserClient = ContentfulUserClient;
|