@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.
Files changed (49) hide show
  1. package/dist/contentful/ContentfulAccess.d.ts +19 -0
  2. package/dist/contentful/ContentfulAccess.js +67 -0
  3. package/dist/contentful/ContentfulApiCommand.d.ts +21 -0
  4. package/dist/contentful/ContentfulApiCommand.js +20 -0
  5. package/dist/contentful/ContentfulApiResponse.d.ts +10 -0
  6. package/dist/contentful/ContentfulApiResponse.js +2 -0
  7. package/dist/contentful/ContentfulAssetClient.d.ts +11 -0
  8. package/dist/contentful/ContentfulAssetClient.js +26 -0
  9. package/dist/contentful/ContentfulAuthClient.d.ts +9 -0
  10. package/dist/contentful/ContentfulAuthClient.js +20 -0
  11. package/dist/contentful/ContentfulChangeSetClient.d.ts +14 -0
  12. package/dist/contentful/ContentfulChangeSetClient.js +35 -0
  13. package/dist/contentful/ContentfulCollectionClient.d.ts +38 -0
  14. package/dist/contentful/ContentfulCollectionClient.js +173 -0
  15. package/dist/contentful/ContentfulContentClient.d.ts +59 -0
  16. package/dist/contentful/ContentfulContentClient.js +208 -0
  17. package/dist/contentful/ContentfulContentClientFactory.d.ts +12 -0
  18. package/dist/contentful/ContentfulContentClientFactory.js +19 -0
  19. package/dist/contentful/ContentfulPageClient.d.ts +43 -0
  20. package/dist/contentful/ContentfulPageClient.js +251 -0
  21. package/dist/contentful/ContentfulSiteConfigClient.d.ts +9 -0
  22. package/dist/contentful/ContentfulSiteConfigClient.js +33 -0
  23. package/dist/contentful/ContentfulUpgradeClient.d.ts +9 -0
  24. package/dist/contentful/ContentfulUpgradeClient.js +17 -0
  25. package/dist/contentful/ContentfulUserClient.d.ts +13 -0
  26. package/dist/contentful/ContentfulUserClient.js +32 -0
  27. package/dist/contentful/IContentfulContentClient.d.ts +52 -0
  28. package/dist/contentful/IContentfulContentClient.js +2 -0
  29. package/dist/contentful/api/ContentfulApi.d.ts +10 -0
  30. package/dist/contentful/api/ContentfulApi.js +82 -0
  31. package/dist/contentful/index.d.ts +12 -0
  32. package/dist/contentful/index.js +28 -0
  33. package/dist/contentful/models/ContentfulAssetData.d.ts +8 -0
  34. package/dist/contentful/models/ContentfulAssetData.js +29 -0
  35. package/dist/contentful/models/ContentfulCollectionData.d.ts +11 -0
  36. package/dist/contentful/models/ContentfulCollectionData.js +98 -0
  37. package/dist/contentful/models/ContentfulData.d.ts +40 -0
  38. package/dist/contentful/models/ContentfulData.js +118 -0
  39. package/dist/contentful/models/ContentfulPageData.d.ts +17 -0
  40. package/dist/contentful/models/ContentfulPageData.js +117 -0
  41. package/dist/contentful/models/ContentfulSiteConfigData.d.ts +10 -0
  42. package/dist/contentful/models/ContentfulSiteConfigData.js +9 -0
  43. package/dist/contentful/models/ContentfulUserData.d.ts +6 -0
  44. package/dist/contentful/models/ContentfulUserData.js +26 -0
  45. package/dist/contentful/models/index.d.ts +6 -0
  46. package/dist/contentful/models/index.js +22 -0
  47. package/dist/contentful/server.d.ts +1 -0
  48. package/dist/contentful/server.js +17 -0
  49. package/package.json +9 -3
@@ -0,0 +1,52 @@
1
+ import { CMAClient } from '@contentful/app-sdk';
2
+ import { PlainClientAPI, QueryOptions } from 'contentful-management';
3
+ import { Environment, User } from '../models';
4
+ import type { ContentfulAssetClient } from './ContentfulAssetClient';
5
+ import type { ContentfulAuthClient } from './ContentfulAuthClient';
6
+ import type { ContentfulChangeSetClient } from './ContentfulChangeSetClient';
7
+ import type { ContentfulCollectionClient } from './ContentfulCollectionClient';
8
+ import type { ContentfulPageClient } from './ContentfulPageClient';
9
+ import type { ContentfulSiteConfigClient } from './ContentfulSiteConfigClient';
10
+ import type { ContentfulUserClient } from './ContentfulUserClient';
11
+ import { ContentfulData } from './models';
12
+ export interface IContentfulContentClient {
13
+ readonly user: User;
14
+ readonly locale: string;
15
+ readonly cma: CMAClient;
16
+ readonly cda: PlainClientAPI;
17
+ readonly cpa: PlainClientAPI;
18
+ readonly auth: ContentfulAuthClient;
19
+ readonly changeSets: ContentfulChangeSetClient;
20
+ readonly files: ContentfulAssetClient;
21
+ readonly pages: ContentfulPageClient;
22
+ readonly collections: ContentfulCollectionClient;
23
+ readonly users: ContentfulUserClient;
24
+ readonly siteConfig: ContentfulSiteConfigClient;
25
+ createEntry<TEntry extends ContentfulData>(contentType: string, entry: ContentfulData.Draft<TEntry>): Promise<TEntry>;
26
+ getEntry<TEntry extends ContentfulData>(args: IContentfulContentClient.GetEntry.Args<TEntry>): Promise<IContentfulContentClient.GetEntry.Result<TEntry>>;
27
+ getEntries<TEntry extends ContentfulData>(args: IContentfulContentClient.GetEntries.Args<TEntry>): Promise<IContentfulContentClient.GetEntries.Result<TEntry>>;
28
+ }
29
+ export declare namespace IContentfulContentClient {
30
+ type EntryQueryOptions = {
31
+ includeLinks?: boolean | number;
32
+ version?: Environment;
33
+ };
34
+ namespace GetEntry {
35
+ type Args<TEntry extends ContentfulData> = EntryQueryOptions & {
36
+ entryId: ContentfulData.EntryId<TEntry>;
37
+ };
38
+ type Result<TEntry extends ContentfulData> = {
39
+ entry: TEntry;
40
+ references: ContentfulData[];
41
+ };
42
+ }
43
+ namespace GetEntries {
44
+ type Args<TEntry extends ContentfulData> = Omit<QueryOptions, 'content_type' | 'include'> & EntryQueryOptions & {
45
+ content_type: ContentfulData.ContentType<TEntry>;
46
+ };
47
+ type Result<TEntry extends ContentfulData> = {
48
+ entries: TEntry[];
49
+ references: ContentfulData[];
50
+ };
51
+ }
52
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,10 @@
1
+ import 'server-only';
2
+ import type { NextRequest, NextResponse as NextResponseType } from 'next/server';
3
+ import { ContentfulApiCommand } from '../ContentfulApiCommand';
4
+ export declare namespace ContentfulApi {
5
+ function process(request: NextRequest, NextResponse: typeof NextResponseType): Promise<NextResponseType<{
6
+ data: ContentfulApiCommand.GetAccessTokens.Result;
7
+ }> | NextResponseType<{
8
+ error: import("@nascentdigital/funnel-core").SerializedIsometricError;
9
+ }>>;
10
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContentfulApi = void 0;
4
+ require("server-only");
5
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
6
+ const api_1 = require("../../api");
7
+ const ContentfulAccess_1 = require("../ContentfulAccess");
8
+ const ContentfulApiCommand_1 = require("../ContentfulApiCommand");
9
+ // namespace
10
+ var ContentfulApi;
11
+ (function (ContentfulApi) {
12
+ // methods
13
+ async function process(request, NextResponse) {
14
+ // process command
15
+ try {
16
+ const data = await processCommand(request);
17
+ return NextResponse.json({ data });
18
+ }
19
+ // or return error on failure
20
+ catch (e) {
21
+ console.error('[ContentfulApi] caught error processing request', e);
22
+ // handle API error
23
+ if (e instanceof funnel_core_1.ApiError) {
24
+ return NextResponse.json({ error: e.serialize() }, { status: e.status });
25
+ }
26
+ // or handle other isometric errors
27
+ else {
28
+ return NextResponse.json({
29
+ error: e instanceof funnel_core_1.IsometricError
30
+ ? e.serialize()
31
+ : new funnel_core_1.ServerError().serialize()
32
+ }, { status: 500 });
33
+ }
34
+ }
35
+ }
36
+ ContentfulApi.process = process;
37
+ })(ContentfulApi || (exports.ContentfulApi = ContentfulApi = {}));
38
+ // handler
39
+ async function processCommand(request) {
40
+ // parse payload (throw if not valid)
41
+ const command = await parseCommand(request);
42
+ // process command
43
+ switch (command.type) {
44
+ case 'GetAccessTokens': {
45
+ const { deliveryAccessToken, previewAccessToken } = api_1.ContentClient.Factory.get().forServer();
46
+ return { deliveryAccessToken, previewAccessToken };
47
+ }
48
+ default:
49
+ throw new funnel_core_1.NotImplementedError();
50
+ }
51
+ }
52
+ // helpers
53
+ async function parseCommand(request) {
54
+ // throw if it's not a post
55
+ if (request.method !== 'POST') {
56
+ throw new funnel_core_1.InvalidOperationError();
57
+ }
58
+ // parse payload (throw if not valid)
59
+ const command = await request.json();
60
+ if (!ContentfulApiCommand_1.ContentfulApiCommand.filter(command)) {
61
+ throw new funnel_core_1.ArgumentError('Invalid command');
62
+ }
63
+ // get site config
64
+ const brand = funnel_core_1.AppConfig.brand();
65
+ const client = api_1.ContentClient.Factory.get().forServer();
66
+ const siteConfig = await client.siteConfig.get({ brand });
67
+ // fail if config can't be resolved
68
+ if (!siteConfig) {
69
+ throw new funnel_core_1.ServerError('Unable to resolve site config');
70
+ }
71
+ // fail if not a match
72
+ else if (!(command.userId in siteConfig.access)) {
73
+ throw new funnel_core_1.NotAuthenticatedError();
74
+ }
75
+ // verify access
76
+ const access = new ContentfulAccess_1.ContentfulAccess(siteConfig.access[command.userId]);
77
+ if (access.token !== command.token || access.isExpired) {
78
+ throw new funnel_core_1.NotAuthenticatedError();
79
+ }
80
+ // return command
81
+ return command;
82
+ }
@@ -0,0 +1,12 @@
1
+ export * from './models';
2
+ export * from './ContentfulAssetClient';
3
+ export * from './ContentfulAuthClient';
4
+ export * from './ContentfulChangeSetClient';
5
+ export * from './ContentfulCollectionClient';
6
+ export * from './ContentfulContentClient';
7
+ export * from './ContentfulContentClientFactory';
8
+ export * from './ContentfulPageClient';
9
+ export * from './ContentfulSiteConfigClient';
10
+ export * from './ContentfulUpgradeClient';
11
+ export * from './ContentfulUserClient';
12
+ export * from './IContentfulContentClient';
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./models"), exports);
18
+ __exportStar(require("./ContentfulAssetClient"), exports);
19
+ __exportStar(require("./ContentfulAuthClient"), exports);
20
+ __exportStar(require("./ContentfulChangeSetClient"), exports);
21
+ __exportStar(require("./ContentfulCollectionClient"), exports);
22
+ __exportStar(require("./ContentfulContentClient"), exports);
23
+ __exportStar(require("./ContentfulContentClientFactory"), exports);
24
+ __exportStar(require("./ContentfulPageClient"), exports);
25
+ __exportStar(require("./ContentfulSiteConfigClient"), exports);
26
+ __exportStar(require("./ContentfulUpgradeClient"), exports);
27
+ __exportStar(require("./ContentfulUserClient"), exports);
28
+ __exportStar(require("./IContentfulContentClient"), exports);
@@ -0,0 +1,8 @@
1
+ import { Schema } from '@nascentdigital/funnel-core';
2
+ import { ContentfulData } from './ContentfulData';
3
+ export type ContentfulAssetData = ContentfulData<ContentfulAssetData.ContentType, Schema.Asset.Id> & Omit<Schema.AssetField.LinkedValue, 'id'>;
4
+ export declare namespace ContentfulAssetData {
5
+ const contentType: "asset";
6
+ type ContentType = typeof contentType;
7
+ function deserialize(data: ContentfulAssetData): Schema.Asset.Linked;
8
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContentfulAssetData = void 0;
4
+ // extension
5
+ var ContentfulAssetData;
6
+ (function (ContentfulAssetData) {
7
+ // constants
8
+ ContentfulAssetData.contentType = 'asset';
9
+ // deserialize
10
+ function deserialize(data) {
11
+ // return asset
12
+ return {
13
+ __root: 'asset',
14
+ type: 'asset',
15
+ value: {
16
+ id: data.id,
17
+ url: data.url,
18
+ type: data.type,
19
+ size: data.size,
20
+ name: data.name,
21
+ description: data.description,
22
+ scope: data.scope,
23
+ tags: data.tags,
24
+ metadata: data.metadata
25
+ }
26
+ };
27
+ }
28
+ ContentfulAssetData.deserialize = deserialize;
29
+ })(ContentfulAssetData || (exports.ContentfulAssetData = ContentfulAssetData = {}));
@@ -0,0 +1,11 @@
1
+ import { RequiredBy, Schema } from '@nascentdigital/funnel-core';
2
+ import { ContentfulData } from './ContentfulData';
3
+ export type ContentfulCollectionData = ContentfulData<ContentfulCollectionData.ContentType, Schema.Collection.Id> & Omit<Schema.Collection.Data, 'id' | 'changeSetId' | 'snapshotId' | 'snapshot'>;
4
+ export declare namespace ContentfulCollectionData {
5
+ const contentType: "collection";
6
+ type ContentType = typeof contentType;
7
+ type ForSchema = Schema.Collection.Data & Pick<ContentfulData, 'references'>;
8
+ type Potential = RequiredBy<Partial<ContentfulCollectionData>, keyof ContentfulData<ContentfulCollectionData.ContentType, Schema.Collection.Id>>;
9
+ function deserialize(data: Potential, props?: ReadonlyArray<Schema.Collection.Data.Props.All>): ForSchema;
10
+ function deserializeRefs(refs: ContentfulData[]): Schema.Collection.References;
11
+ }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContentfulCollectionData = void 0;
4
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
5
+ const ContentfulAssetData_1 = require("./ContentfulAssetData");
6
+ // extension
7
+ var ContentfulCollectionData;
8
+ (function (ContentfulCollectionData) {
9
+ // constants
10
+ ContentfulCollectionData.contentType = 'collection';
11
+ function deserialize(data, props = funnel_core_1.Schema.Collection.Data.Props.all) {
12
+ var _a;
13
+ // create base collection
14
+ const collection = {
15
+ __root: 'collection',
16
+ id: data.id,
17
+ createdOn: data.createdOn,
18
+ updatedOn: data.updatedOn,
19
+ references: (_a = data.references) !== null && _a !== void 0 ? _a : []
20
+ };
21
+ // helper
22
+ const bindProp = (prop, target, transform) => {
23
+ if (prop in data) {
24
+ collection[target] = transform(data[prop]);
25
+ }
26
+ };
27
+ // bind required props to page
28
+ for (const prop of props) {
29
+ switch (prop) {
30
+ // handled by base
31
+ case 'id':
32
+ case 'createdOn':
33
+ case 'updatedOn':
34
+ break;
35
+ // direct transforms
36
+ case 'groupId':
37
+ case 'type':
38
+ case 'brand':
39
+ case 'language':
40
+ case 'version':
41
+ case 'name':
42
+ case 'state':
43
+ case 'errors':
44
+ case 'pageIds':
45
+ case 'tags':
46
+ case 'publishedOn':
47
+ bindProp(prop, prop, value => value !== null && value !== void 0 ? value : undefined);
48
+ break;
49
+ // content
50
+ case 'fields':
51
+ bindProp(prop, prop, value => value !== null && value !== void 0 ? value : {});
52
+ break;
53
+ // ignore
54
+ case 'files':
55
+ case 'collections':
56
+ case 'snapshot':
57
+ case 'snapshotId':
58
+ case 'changeSetId':
59
+ break;
60
+ // unhandled
61
+ default:
62
+ throw new funnel_core_1.NotImplementedError(`Missing support for transforming collection "${prop}" prop`);
63
+ }
64
+ }
65
+ // return collection
66
+ return collection;
67
+ }
68
+ ContentfulCollectionData.deserialize = deserialize;
69
+ // deserialize references
70
+ function deserializeRefs(refs) {
71
+ // setup
72
+ const files = {};
73
+ const collections = {};
74
+ // loop over references and serialize
75
+ for (const ref of refs) {
76
+ switch (ref.__type) {
77
+ // asset
78
+ case ContentfulAssetData_1.ContentfulAssetData.contentType: {
79
+ const assetRef = ref;
80
+ files[assetRef.id] = ContentfulAssetData_1.ContentfulAssetData.deserialize(assetRef);
81
+ break;
82
+ }
83
+ // collection
84
+ case ContentfulCollectionData.contentType: {
85
+ const collectionRef = ref;
86
+ collections[collectionRef.id] = ContentfulCollectionData.deserialize(collectionRef, funnel_core_1.Schema.Collection.Data.AsLink.props);
87
+ break;
88
+ }
89
+ }
90
+ }
91
+ // return
92
+ return {
93
+ files,
94
+ collections
95
+ };
96
+ }
97
+ ContentfulCollectionData.deserializeRefs = deserializeRefs;
98
+ })(ContentfulCollectionData || (exports.ContentfulCollectionData = ContentfulCollectionData = {}));
@@ -0,0 +1,40 @@
1
+ import type { EntryAPI } from '@contentful/app-sdk';
2
+ import type { Entry } from 'contentful';
3
+ import type { EntryProps } from 'contentful-management';
4
+ export type ContentfulData<TType extends string = string, TId extends string = string> = {
5
+ __type: TType;
6
+ __version: number;
7
+ id: TId;
8
+ createdOn: number;
9
+ updatedOn: number;
10
+ references: ContentfulData.References;
11
+ };
12
+ export declare namespace ContentfulData {
13
+ type ContentType<T extends ContentfulData> = T['__type'];
14
+ type EntryId<T extends ContentfulData> = T['id'];
15
+ type References = Array<Link.Entry | Link.Asset>;
16
+ type Draft<T extends ContentfulData> = Omit<T, keyof ContentfulData>;
17
+ type Link<TType extends Link.Type = Link.Type> = {
18
+ sys: {
19
+ type: 'Link';
20
+ linkType: TType;
21
+ id: string;
22
+ };
23
+ };
24
+ namespace Link {
25
+ type Type = 'Asset' | 'Entry' | 'Upload';
26
+ type Asset = Link<'Asset'>;
27
+ type Entry = Link<'Entry'>;
28
+ function create<TType extends Type>(id: string, linkType: TType): Link<TType>;
29
+ }
30
+ type Fields<TData extends Record<string, any>> = {
31
+ [TKey in Exclude<keyof TData, keyof ContentfulData>]: {
32
+ [locale: string]: TData[TKey];
33
+ };
34
+ };
35
+ function toEntryData<T extends Record<string, any>>(entry: T, locale: string): Fields<T>;
36
+ function fromEntryData<T extends ContentfulData>(entry: EntryAPI): T;
37
+ function fromCdaData<T extends ContentfulData>({ sys, fields }: Entry): T;
38
+ function fromCmaData<T extends ContentfulData>({ sys, fields }: EntryProps, locale: string): T;
39
+ function findReferences(source: object): References;
40
+ }
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContentfulData = void 0;
4
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
5
+ var ContentfulData;
6
+ (function (ContentfulData) {
7
+ let Link;
8
+ (function (Link) {
9
+ // helpers
10
+ function create(id, linkType) {
11
+ return {
12
+ sys: {
13
+ type: 'Link',
14
+ linkType,
15
+ id
16
+ }
17
+ };
18
+ }
19
+ Link.create = create;
20
+ })(Link = ContentfulData.Link || (ContentfulData.Link = {}));
21
+ // helpers
22
+ function toEntryData(entry, locale) {
23
+ return Object.entries(entry).reduce((entryData, [keyRaw, value]) => {
24
+ // map entry (bucket under locale)
25
+ const key = keyRaw;
26
+ entryData[key] = { [locale]: value };
27
+ // keep reducing
28
+ return entryData;
29
+ }, {});
30
+ }
31
+ ContentfulData.toEntryData = toEntryData;
32
+ function fromEntryData(entry) {
33
+ // get sys
34
+ const sys = entry.getSys();
35
+ // simplify fields (remove locale)
36
+ const normalizedFields = {};
37
+ for (const key in entry.fields) {
38
+ normalizedFields[key] = entry.fields[key].getValue();
39
+ }
40
+ // return normalized form
41
+ return Object.assign({ __type: sys.contentType.sys.id, __version: sys.version, id: sys.id, createdOn: new Date(sys.createdAt).getTime(), updatedOn: new Date(sys.updatedAt).getTime() }, normalizedFields);
42
+ }
43
+ ContentfulData.fromEntryData = fromEntryData;
44
+ function fromCdaData({ sys, fields }) {
45
+ // simplify fields (remove locale)
46
+ const normalizedFields = {};
47
+ for (const key in fields) {
48
+ normalizedFields[key] = fields[key];
49
+ }
50
+ // return normalized form
51
+ return Object.assign({ __type: sys.contentType.sys.id, __version: sys.revision, id: sys.id, createdOn: new Date(sys.createdAt).getTime(), updatedOn: new Date(sys.updatedAt).getTime() }, normalizedFields);
52
+ }
53
+ ContentfulData.fromCdaData = fromCdaData;
54
+ function fromCmaData({ sys, fields }, locale) {
55
+ // simplify fields (remove locale)
56
+ const normalizedFields = {};
57
+ for (const key in fields) {
58
+ normalizedFields[key] = fields[key][locale];
59
+ }
60
+ // return normalized form
61
+ return Object.assign({ __type: sys.contentType.sys.id, __version: sys.version, id: sys.id, createdOn: new Date(sys.createdAt).getTime(), updatedOn: new Date(sys.updatedAt).getTime() }, normalizedFields);
62
+ }
63
+ ContentfulData.fromCmaData = fromCmaData;
64
+ function findReferences(source) {
65
+ // prepare sets
66
+ const references = [];
67
+ // extract actual refs
68
+ funnel_core_1.ObjectUtils.walk(source, ({ value }) => {
69
+ // track assets
70
+ if (funnel_core_1.Schema.Asset.filter(value)) {
71
+ // track file (if it's real)
72
+ const assetId = funnel_core_1.Schema.Asset.getId(value);
73
+ if (assetId) {
74
+ references.push(ContentfulData.Link.create(assetId, 'Entry'));
75
+ }
76
+ // don't recurse
77
+ return false;
78
+ }
79
+ // track page links
80
+ else if (funnel_core_1.Schema.Field.Data.InternalLink.filter(value)) {
81
+ // track page (only if the id's real)
82
+ const pageId = funnel_core_1.Schema.Field.Data.InternalLink.getId(value);
83
+ if (pageId && pageId !== funnel_core_1.Schema.Page.Id.draft) {
84
+ references.push(ContentfulData.Link.create(pageId, 'Entry'));
85
+ }
86
+ // don't recurse
87
+ return false;
88
+ }
89
+ // transform collection refs
90
+ else if (funnel_core_1.Schema.Field.Data.Collection.Ref.filter(value)) {
91
+ // track collection (only if the id's real)
92
+ const collectionId = funnel_core_1.Schema.Field.Data.Collection.Ref.getId(value);
93
+ if (collectionId && collectionId !== funnel_core_1.Schema.Collection.Id.draft) {
94
+ references.push(ContentfulData.Link.create(collectionId, 'Entry'));
95
+ }
96
+ // don't recurse
97
+ return false;
98
+ }
99
+ // transform page refs
100
+ else if (funnel_core_1.Schema.Field.Data.Page.filter(value)) {
101
+ // track page (only if the id's real)
102
+ const pageId = funnel_core_1.Schema.Field.Data.Page.getId(value);
103
+ if (pageId && pageId !== funnel_core_1.Schema.Page.Id.draft) {
104
+ references.push(ContentfulData.Link.create(pageId, 'Entry'));
105
+ }
106
+ // don't recurse
107
+ return false;
108
+ }
109
+ // otherwise recurse deeper
110
+ else {
111
+ return true;
112
+ }
113
+ });
114
+ // return references
115
+ return references;
116
+ }
117
+ ContentfulData.findReferences = findReferences;
118
+ })(ContentfulData || (exports.ContentfulData = ContentfulData = {}));
@@ -0,0 +1,17 @@
1
+ import { RequiredBy, Schema } from '@nascentdigital/funnel-core';
2
+ import { ContentfulData } from './ContentfulData';
3
+ export type ContentfulPageData = ContentfulData<ContentfulPageData.ContentType, Schema.Page.Id> & Omit<Schema.Page.Data, 'id' | 'changeSetId' | 'snapshotId' | 'snapshot'>;
4
+ export declare namespace ContentfulPageData {
5
+ const contentType: "page";
6
+ type ContentType = typeof contentType;
7
+ const referencesSpec: {
8
+ readonly page: "pages";
9
+ readonly collection: "collections";
10
+ readonly asset: "files";
11
+ };
12
+ type ReferencesSpec = typeof referencesSpec;
13
+ type ForSchema = Schema.Page.Data & Pick<ContentfulData, 'references'>;
14
+ type Potential = RequiredBy<Partial<ContentfulPageData>, keyof ContentfulData<ContentfulPageData.ContentType, Schema.Page.Id>>;
15
+ function deserialize(data: Potential, props?: ReadonlyArray<Schema.Page.Data.Props.All>): ForSchema;
16
+ function deserializeRefs(refs: ContentfulData[]): Schema.Page.References;
17
+ }
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContentfulPageData = void 0;
4
+ const funnel_core_1 = require("@nascentdigital/funnel-core");
5
+ const ContentfulAssetData_1 = require("./ContentfulAssetData");
6
+ const ContentfulCollectionData_1 = require("./ContentfulCollectionData");
7
+ // extension
8
+ var ContentfulPageData;
9
+ (function (ContentfulPageData) {
10
+ // constants
11
+ ContentfulPageData.contentType = 'page';
12
+ ContentfulPageData.referencesSpec = {
13
+ 'page': 'pages',
14
+ 'collection': 'collections',
15
+ 'asset': 'files'
16
+ };
17
+ function deserialize(data, props = funnel_core_1.Schema.Page.Data.Props.all) {
18
+ var _a;
19
+ // create base page
20
+ const page = {
21
+ __root: 'page',
22
+ id: data.id,
23
+ createdOn: data.createdOn,
24
+ updatedOn: data.updatedOn,
25
+ references: (_a = data.references) !== null && _a !== void 0 ? _a : []
26
+ };
27
+ // helper
28
+ const bindProp = (prop, target, transform) => {
29
+ if (prop in data) {
30
+ page[target] = transform(data[prop]);
31
+ }
32
+ };
33
+ // bind required props to page
34
+ for (const prop of props) {
35
+ switch (prop) {
36
+ // handled by base
37
+ case 'id':
38
+ case 'createdOn':
39
+ case 'updatedOn':
40
+ break;
41
+ // direct transforms
42
+ case 'groupId':
43
+ case 'brand':
44
+ case 'region':
45
+ case 'language':
46
+ case 'type':
47
+ case 'slug':
48
+ case 'url':
49
+ case 'name':
50
+ case 'preview':
51
+ case 'state':
52
+ case 'errors':
53
+ case 'tags':
54
+ case 'publishedOn':
55
+ case 'publication':
56
+ bindProp(prop, prop, value => value !== null && value !== void 0 ? value : undefined);
57
+ break;
58
+ // content
59
+ case 'discover':
60
+ case 'content':
61
+ bindProp(prop, prop, value => value !== null && value !== void 0 ? value : {});
62
+ break;
63
+ // ignore
64
+ case 'files':
65
+ case 'pages':
66
+ case 'collections':
67
+ case 'snapshot':
68
+ case 'snapshotId':
69
+ case 'changeSetId':
70
+ break;
71
+ // unhandled
72
+ default:
73
+ throw new funnel_core_1.NotImplementedError(`Missing support for transforming page "${prop}" prop`);
74
+ }
75
+ }
76
+ // return page
77
+ return page;
78
+ }
79
+ ContentfulPageData.deserialize = deserialize;
80
+ // deserialize references
81
+ function deserializeRefs(refs) {
82
+ // setup
83
+ const files = {};
84
+ const collections = {};
85
+ const pages = {};
86
+ // loop over references and serialize
87
+ for (const ref of refs) {
88
+ switch (ref.__type) {
89
+ // asset
90
+ case ContentfulAssetData_1.ContentfulAssetData.contentType: {
91
+ const assetRef = ref;
92
+ files[assetRef.id] = ContentfulAssetData_1.ContentfulAssetData.deserialize(assetRef);
93
+ break;
94
+ }
95
+ // collection
96
+ case ContentfulCollectionData_1.ContentfulCollectionData.contentType: {
97
+ const collectionRef = ref;
98
+ collections[collectionRef.id] = ContentfulCollectionData_1.ContentfulCollectionData.deserialize(collectionRef, funnel_core_1.Schema.Collection.Data.AsLink.props);
99
+ break;
100
+ }
101
+ // page
102
+ case ContentfulPageData.contentType: {
103
+ const pageRef = ref;
104
+ pages[pageRef.id] = ContentfulPageData.deserialize(pageRef, funnel_core_1.Schema.Page.Data.Props.all);
105
+ break;
106
+ }
107
+ }
108
+ }
109
+ // return
110
+ return {
111
+ files,
112
+ collections,
113
+ pages
114
+ };
115
+ }
116
+ ContentfulPageData.deserializeRefs = deserializeRefs;
117
+ })(ContentfulPageData || (exports.ContentfulPageData = ContentfulPageData = {}));
@@ -0,0 +1,10 @@
1
+ import { SiteConfig, User } from '../../models';
2
+ import { ContentfulAccess } from '../ContentfulAccess';
3
+ import { ContentfulData } from './ContentfulData';
4
+ export type ContentfulSiteConfigData = Omit<SiteConfig.Data, 'id'> & ContentfulData<ContentfulSiteConfigData.ContentType, SiteConfig.Id> & {
5
+ access: Record<User.Id, ContentfulAccess.Data>;
6
+ };
7
+ export declare namespace ContentfulSiteConfigData {
8
+ const contentType: "siteConfig";
9
+ type ContentType = typeof contentType;
10
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContentfulSiteConfigData = void 0;
4
+ // extension
5
+ var ContentfulSiteConfigData;
6
+ (function (ContentfulSiteConfigData) {
7
+ // constants
8
+ ContentfulSiteConfigData.contentType = 'siteConfig';
9
+ })(ContentfulSiteConfigData || (exports.ContentfulSiteConfigData = ContentfulSiteConfigData = {}));
@@ -0,0 +1,6 @@
1
+ import { UserAPI } from '@contentful/app-sdk';
2
+ import { Role } from '../../models';
3
+ export type ContentfulUserData = UserAPI;
4
+ export declare namespace ContentfulUserData {
5
+ function parseRole(role: string): Role;
6
+ }