gatsby-theme-q3 3.2.0 → 3.2.1

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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.2.1](https://github.com/3merge/q/compare/v3.2.0...v3.2.1) (2022-02-09)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * misc domain issues ([17cb74b](https://github.com/3merge/q/commit/17cb74b927721f11b5fcd8f8a9a1a28a86867048))
12
+
13
+
14
+
15
+
16
+
6
17
  # [3.2.0](https://github.com/3merge/q/compare/v3.1.5...v3.2.0) (2022-02-09)
7
18
 
8
19
 
package/gatsby-browser.js CHANGED
@@ -11,6 +11,11 @@ export {
11
11
  export const onClientEntry = async () => {
12
12
  if (!browser.isBrowserReady()) return;
13
13
 
14
+ // set api default root
15
+ axios.defaults.baseURL =
16
+ process.env.GATSBY_APP_BASE_URL ||
17
+ 'http://localhost:9000';
18
+
14
19
  // set language default
15
20
  axios.defaults.headers['Content-Language'] =
16
21
  window.localStorage.getItem('q3-locale') || 'en';
package/gatsby-config.js CHANGED
@@ -4,14 +4,7 @@ require('dotenv').config();
4
4
  const genKey = (url) =>
5
5
  String(url).includes('netlify') ? 'disallow' : 'allow';
6
6
 
7
- module.exports = ({
8
- siteUrl,
9
- title,
10
- brandingColor,
11
- icon,
12
- netlify,
13
- ...options
14
- }) => {
7
+ module.exports = (options) => {
15
8
  const plugins = [
16
9
  {
17
10
  resolve: 'gatsby-theme-q3-mui',
@@ -48,24 +41,20 @@ module.exports = ({
48
41
  },
49
42
  },
50
43
  },
51
- ];
52
-
53
- if (netlify)
54
- plugins.push({
44
+ {
55
45
  resolve: 'gatsby-plugin-netlify',
56
46
  options: {
57
47
  generateMatchPathRewrites: true,
58
48
  },
59
- });
60
-
61
- if (siteUrl)
62
- plugins.push({
49
+ },
50
+ {
63
51
  resolve: 'gatsby-plugin-canonical-urls',
64
52
  options: {
65
53
  stripQueryString: true,
66
- siteUrl,
54
+ siteUrl: process.env.URL,
67
55
  },
68
- });
56
+ },
57
+ ];
69
58
 
70
59
  return {
71
60
  plugins,
package/gatsby-node.js CHANGED
@@ -70,7 +70,6 @@ exports.onCreatePage = async ({ page, actions }) => {
70
70
  createPage({
71
71
  ...page,
72
72
  context: {
73
- contentful_id: 'APP',
74
73
  to: '/app',
75
74
  },
76
75
  });
@@ -17,8 +17,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
17
17
 
18
18
  const PageWrapper = ({
19
19
  children,
20
- includeLoader,
21
- includeLocale
20
+ includeLoader
22
21
  }) => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_SearchEngine.default, null), includeLoader && /*#__PURE__*/_react.default.createElement(_components.Loader, null), children);
23
22
 
24
23
  PageWrapper.defaultProps = {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getStartUrl = exports.generateMetaTitleOptions = exports.generateMetaDescriptionOptions = exports.generateManifest = exports.generateIcons = exports.generateBrand = exports.default = exports.Manifest = void 0;
6
+ exports.getStartUrl = exports.generateMetaTitleOptions = exports.generateMetaDescriptionOptions = exports.generateManifest = exports.generateIcons = exports.generateBrand = exports.default = void 0;
7
7
 
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
 
@@ -69,13 +69,6 @@ const generateManifest = (site = {}) => ({
69
69
 
70
70
  exports.generateManifest = generateManifest;
71
71
 
72
- const Manifest = props => (0, _lodash.isObject)(props) ? /*#__PURE__*/_react.default.createElement("link", {
73
- rel: "manifest",
74
- href: `data:application/manifest+json,${encodeURIComponent(JSON.stringify(props))}`
75
- }) : null;
76
-
77
- exports.Manifest = Manifest;
78
-
79
72
  const SEO = ({
80
73
  description,
81
74
  lang,
@@ -85,12 +78,13 @@ const SEO = ({
85
78
  const site = (0, _useSiteMetaData.default)();
86
79
  const metaDescription = description || site.description;
87
80
  const metaTitle = title || site.title;
81
+ const manifestData = generateManifest(site);
88
82
  return /*#__PURE__*/_react.default.createElement(_reactHelmet.Helmet, {
89
83
  htmlAttributes: {
90
84
  lang
91
85
  },
92
86
  title: metaTitle,
93
- titleTemplate: generateBrand((0, _lodash.get)(site, 'brand', 'Q3')),
87
+ titleTemplate: generateBrand(site.brand),
94
88
  meta: [...generateMetaTitleOptions(metaTitle), ...generateMetaDescriptionOptions(metaDescription), {
95
89
  property: 'og:type',
96
90
  content: 'website'
@@ -98,7 +92,10 @@ const SEO = ({
98
92
  name: 'twitter:card',
99
93
  content: 'summary'
100
94
  }].concat(meta)
101
- }, /*#__PURE__*/_react.default.createElement(Manifest, generateManifest(site)), /*#__PURE__*/_react.default.createElement("link", {
95
+ }, (0, _lodash.isObject)(manifestData) ? /*#__PURE__*/_react.default.createElement("link", {
96
+ rel: "manifest",
97
+ href: `data:application/manifest+json,${encodeURIComponent(JSON.stringify(manifestData))}`
98
+ }) : null, /*#__PURE__*/_react.default.createElement("link", {
102
99
  rel: "icon",
103
100
  href: site.favicon
104
101
  }));
@@ -7,8 +7,6 @@ exports.default = void 0;
7
7
 
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
 
10
- var _axios = _interopRequireDefault(require("axios"));
11
-
12
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
13
11
 
14
12
  var _q3UiPermissions = _interopRequireDefault(require("q3-ui-permissions"));
@@ -16,27 +14,12 @@ var _q3UiPermissions = _interopRequireDefault(require("q3-ui-permissions"));
16
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
15
 
18
16
  /* eslint-disable import/no-extraneous-dependencies */
19
- const setBaseUrlForRest = (baseURL = process.env.GATSBY_APP_BASE_URL || 'http://localhost:9000') => {
20
- _axios.default.defaults.baseURL = baseURL;
21
- return _axios.default.defaults;
22
- };
23
-
24
17
  const Wrapper = ({
25
- baseURL,
26
18
  children
27
- }) => {
28
- setBaseUrlForRest(baseURL);
29
- return /*#__PURE__*/_react.default.createElement(_q3UiPermissions.default, null, children);
30
- };
19
+ }) => /*#__PURE__*/_react.default.createElement(_q3UiPermissions.default, null, children);
31
20
 
32
- Wrapper.defaultProps = {
33
- baseURL: undefined
34
- };
35
21
  Wrapper.propTypes = {
36
- baseURL: _propTypes.default.string,
37
- children: _propTypes.default.node.isRequired,
38
- // eslint-disable-next-line
39
- locale: _propTypes.default.object.isRequired
22
+ children: _propTypes.default.node.isRequired
40
23
  };
41
24
  var _default = Wrapper;
42
25
  exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-theme-q3",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "peerDependencies": {
@@ -28,13 +28,13 @@
28
28
  "gatsby-plugin-robots-txt": "^1.6.14",
29
29
  "gatsby-plugin-sharp": "^4.2.0",
30
30
  "gatsby-plugin-sitemap": "^5.2.0",
31
- "gatsby-theme-q3-mui": "^3.2.0",
31
+ "gatsby-theme-q3-mui": "^3.2.1",
32
32
  "gatsby-transformer-sharp": "^4.2.0",
33
33
  "lodash": "^4.17.20",
34
34
  "process": "^0.11.10",
35
35
  "prop-types": "^15.7.2",
36
36
  "q3-ui-helpers": "^3.2.0",
37
- "q3-ui-locale": "^3.2.0",
37
+ "q3-ui-locale": "^3.2.1",
38
38
  "query-string": "^7.0.1",
39
39
  "react-helmet": "^6.1.0",
40
40
  "react-share": "^4.3.1",
@@ -42,5 +42,5 @@
42
42
  "transform-loader": "^0.2.4",
43
43
  "yarn": "^1.22.17"
44
44
  },
45
- "gitHead": "e7b26a194d8779024212ba64ca440222c28d82c7"
45
+ "gitHead": "b9ee55eb96e7d61f86f9d5d091d8a9d770c720cc"
46
46
  }
@@ -3,11 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import { Loader } from 'q3-admin/lib/components';
4
4
  import SearchEngine from './SearchEngine';
5
5
 
6
- const PageWrapper = ({
7
- children,
8
- includeLoader,
9
- includeLocale,
10
- }) => (
6
+ const PageWrapper = ({ children, includeLoader }) => (
11
7
  <>
12
8
  <SearchEngine />
13
9
  {includeLoader && <Loader />}
@@ -68,20 +68,11 @@ export const generateManifest = (site = {}) => ({
68
68
  theme_color: site.color,
69
69
  });
70
70
 
71
- export const Manifest = (props) =>
72
- isObject(props) ? (
73
- <link
74
- rel="manifest"
75
- href={`data:application/manifest+json,${encodeURIComponent(
76
- JSON.stringify(props),
77
- )}`}
78
- />
79
- ) : null;
80
-
81
71
  const SEO = ({ description, lang, meta, title }) => {
82
72
  const site = useSiteMetaData();
83
73
  const metaDescription = description || site.description;
84
74
  const metaTitle = title || site.title;
75
+ const manifestData = generateManifest(site);
85
76
 
86
77
  return (
87
78
  <Helmet
@@ -89,9 +80,7 @@ const SEO = ({ description, lang, meta, title }) => {
89
80
  lang,
90
81
  }}
91
82
  title={metaTitle}
92
- titleTemplate={generateBrand(
93
- get(site, 'brand', 'Q3'),
94
- )}
83
+ titleTemplate={generateBrand(site.brand)}
95
84
  meta={[
96
85
  ...generateMetaTitleOptions(metaTitle),
97
86
  ...generateMetaDescriptionOptions(metaDescription),
@@ -105,7 +94,14 @@ const SEO = ({ description, lang, meta, title }) => {
105
94
  },
106
95
  ].concat(meta)}
107
96
  >
108
- <Manifest {...generateManifest(site)} />
97
+ {isObject(manifestData) ? (
98
+ <link
99
+ rel="manifest"
100
+ href={`data:application/manifest+json,${encodeURIComponent(
101
+ JSON.stringify(manifestData),
102
+ )}`}
103
+ />
104
+ ) : null}
109
105
  <link rel="icon" href={site.favicon} />
110
106
  </Helmet>
111
107
  );
@@ -1,32 +1,14 @@
1
1
  /* eslint-disable import/no-extraneous-dependencies */
2
2
  import React from 'react';
3
- import axios from 'axios';
4
3
  import PropTypes from 'prop-types';
5
4
  import AuthProvider from 'q3-ui-permissions';
6
5
 
7
- const setBaseUrlForRest = (
8
- baseURL = process.env.GATSBY_APP_BASE_URL ||
9
- 'http://localhost:9000',
10
- ) => {
11
- axios.defaults.baseURL = baseURL;
12
- return axios.defaults;
13
- };
14
-
15
- const Wrapper = ({ baseURL, children }) => {
16
- setBaseUrlForRest(baseURL);
17
- return <AuthProvider>{children}</AuthProvider>;
18
- };
19
-
20
- Wrapper.defaultProps = {
21
- baseURL: undefined,
22
- };
6
+ const Wrapper = ({ children }) => (
7
+ <AuthProvider>{children}</AuthProvider>
8
+ );
23
9
 
24
10
  Wrapper.propTypes = {
25
- baseURL: PropTypes.string,
26
11
  children: PropTypes.node.isRequired,
27
-
28
- // eslint-disable-next-line
29
- locale: PropTypes.object.isRequired,
30
12
  };
31
13
 
32
14
  export default Wrapper;
@@ -1,62 +0,0 @@
1
- import { get } from 'lodash';
2
- import config from '../gatsby-config';
3
-
4
- const CANONICAL = 'gatsby-plugin-canonical-urls';
5
- const ROBOTS = 'gatsby-plugin-robots-txt';
6
-
7
- const ENV = {
8
- contentfulSpaceID: 1,
9
- contentfulAccessToken: 1,
10
- };
11
-
12
- const containsResolver = (plugins = [], name) =>
13
- plugins.find(
14
- (p) => typeof p === 'object' && p.resolve === name,
15
- );
16
-
17
- const checkPlugins = (args = {}, plugin) => {
18
- const { plugins } = config({ ...ENV, ...args });
19
- const statement = expect(
20
- containsResolver(plugins, plugin),
21
- );
22
-
23
- return {
24
- has: () => statement.not.toBeUndefined(),
25
- hasNot: () => statement.toBeUndefined(),
26
- };
27
- };
28
-
29
- describe('gatsby-config', () => {
30
- describe('plugins', () => {
31
- it('should include conditional plugins', () =>
32
- [CANONICAL].forEach((name) =>
33
- checkPlugins(
34
- {
35
- brandingColor: '#FFF',
36
- title: 'Foo',
37
- siteUrl: 'https://google.ca',
38
- },
39
- name,
40
- ).has(),
41
- ));
42
-
43
- it('should exclude conditional plugins', () =>
44
- [CANONICAL].forEach((name) =>
45
- checkPlugins({}, name).hasNot(),
46
- ));
47
-
48
- it.each([
49
- ['https://dev.netlify.3merge.com', 'disallow'],
50
- ['https://3merge.com', 'allow'],
51
- ])('should disable indexing', (url, key) => {
52
- process.env.URL = url;
53
- const { plugins } = config({ ...ENV });
54
- const res = containsResolver(plugins, ROBOTS);
55
- const prod = get(
56
- res,
57
- 'options.env.production.policy',
58
- )[0];
59
- expect(prod).toHaveProperty(key, '/');
60
- });
61
- });
62
- });
@@ -1,13 +0,0 @@
1
- const path = require('path');
2
- const loadContent = require('../loadContent');
3
-
4
- describe('loadContent', () => {
5
- it('should fetch all content from directory', () => {
6
- const out = loadContent(
7
- path.resolve(__dirname, '../../__fixtures__'),
8
- );
9
-
10
- expect(out).toHaveProperty('en');
11
- expect(out).toHaveProperty('fr');
12
- });
13
- });
@@ -1,139 +0,0 @@
1
- const {
2
- genCursor,
3
- appendSiblingsToContext,
4
- getPreviousArchiveUrl,
5
- getNextArchiveUrl,
6
- getNumberOfPages,
7
- paginateArchiveContext,
8
- } = require('../pagination');
9
-
10
- const genEntries = () => {
11
- const entries = [];
12
- for (let i = 0; i < 30; i += 1) entries.push(i);
13
- return entries;
14
- };
15
-
16
- describe('pagination', () => {
17
- describe('"genCursor"', () => {
18
- const stub = ['foo', 'bar', 'quuz', 'garply'];
19
- const cursor = genCursor(stub, 2);
20
- // current index targets "quuz"
21
-
22
- it('should identify first item', () => {
23
- expect(cursor.first).toMatch('foo');
24
- });
25
-
26
- it('should identify last item', () => {
27
- expect(cursor.last).toMatch('garply');
28
- });
29
-
30
- it('should identify next item', () => {
31
- expect(cursor.next).toMatch('garply');
32
- });
33
-
34
- it('should identify previous item', () => {
35
- expect(cursor.prev).toMatch('bar');
36
- });
37
-
38
- it('should identify first position', () => {
39
- expect(cursor.isFirst).toBeFalsy();
40
- expect(genCursor(stub, 0).isFirst).toBeTruthy();
41
- });
42
-
43
- it('should identify last position', () => {
44
- expect(cursor.isLast).toBeFalsy();
45
- expect(genCursor(stub, 3).isLast).toBeTruthy();
46
- });
47
- });
48
-
49
- describe('"appendSiblingsToContext"', () => {
50
- const mockContentfulEntry = (id) => ({
51
- contentful_id: id,
52
- });
53
-
54
- const stubWithContentful = [
55
- mockContentfulEntry(1),
56
- mockContentfulEntry(2),
57
- mockContentfulEntry(3),
58
- ];
59
-
60
- it('should map contentful entries using cursor', () => {
61
- const entries = appendSiblingsToContext(
62
- stubWithContentful,
63
- );
64
- expect(entries[0]).toMatchObject({
65
- prev: 3,
66
- next: 2,
67
- });
68
- expect(entries[2]).toMatchObject({
69
- prev: 2,
70
- next: 1,
71
- });
72
- });
73
- });
74
-
75
- describe('"getPreviousArchiveUrl"', () => {
76
- it('should return null', () => {
77
- expect(getPreviousArchiveUrl('/foo', 1)).toBeNull();
78
- });
79
-
80
- it('should return archive', () => {
81
- expect(getPreviousArchiveUrl('/foo', 2)).toEqual(
82
- '/foo',
83
- );
84
- });
85
-
86
- it('should return archive sub-directory', () => {
87
- expect(getPreviousArchiveUrl('/foo', 3)).toEqual(
88
- '/foo/2',
89
- );
90
- });
91
- });
92
-
93
- describe('"getNextArchiveUrl"', () => {
94
- it('should return sub-directory', () => {
95
- expect(getNextArchiveUrl('/foo', 8, 9)).toEqual(
96
- '/foo/9',
97
- );
98
- });
99
-
100
- it('should return null', () => {
101
- expect(getNextArchiveUrl('/foo', 9, 9)).toBeNull();
102
- });
103
- });
104
-
105
- describe('"getNumberOfPages"', () => {
106
- it('should return number divisible by', () => {
107
- expect(getNumberOfPages(genEntries(), 5)).toBe(6);
108
- });
109
- });
110
-
111
- describe('"paginateArchiveContext"', () => {
112
- it('should return pagination meta', () => {
113
- // default 15 per page
114
- const res = paginateArchiveContext(
115
- genEntries(),
116
- '/foo',
117
- );
118
-
119
- expect(res).toHaveLength(2);
120
- expect(res[0]).toMatchObject({
121
- path: '/foo',
122
- limit: 15,
123
- skip: 0,
124
- pageNum: 0,
125
- prev: null,
126
- next: '/foo/2',
127
- });
128
-
129
- expect(res[1]).toMatchObject({
130
- path: '/foo/2',
131
- limit: 15,
132
- skip: 15,
133
- pageNum: 1,
134
- prev: '/foo',
135
- next: null,
136
- });
137
- });
138
- });
139
- });
@@ -1,21 +0,0 @@
1
- const slug = require('../slug');
2
-
3
- describe('slug', () => {
4
- it('should combine use slug attribute', () => {
5
- expect(
6
- slug({ slug: 'already-formatted-as-slug' }),
7
- ).toMatch('/already-formatted-as-slug');
8
- });
9
-
10
- it('should combine use title attribute', () => {
11
- expect(
12
- slug({ title: 'This is a post' }, 'foos'),
13
- ).toMatch('/foos/this-is-a-post');
14
- });
15
-
16
- it('should combine use name attribute', () => {
17
- expect(slug({ name: "Post's name" }, '/foos')).toMatch(
18
- '/foos/posts-name',
19
- );
20
- });
21
- });
@@ -1,42 +0,0 @@
1
- const { get } = require('lodash');
2
- const { resolve } = require('path');
3
- const {
4
- appendSiblingsToContext,
5
- paginateArchiveContext,
6
- } = require('./pagination');
7
-
8
- module.exports = ({
9
- archiveComponentRelativePath,
10
- createPage,
11
- detailComponentRelativePath,
12
- nodesKeyName,
13
- slug,
14
- }) => async ({ data, errors }) => {
15
- if (errors) throw errors;
16
- const { nodes = [] } = get(data, nodesKeyName, {
17
- nodes: [],
18
- });
19
-
20
- const archives = appendSiblingsToContext(nodes).map(
21
- (context) =>
22
- createPage({
23
- path:
24
- // see slugType for more details on this field
25
- context.to || `/${slug}/${context.contentful_id}`,
26
- component: resolve(detailComponentRelativePath),
27
- context,
28
- }),
29
- );
30
-
31
- const entries = paginateArchiveContext(nodes, slug).map(
32
- ({ path, ...context }) =>
33
- createPage({
34
- component: resolve(archiveComponentRelativePath),
35
- path,
36
- context,
37
- }),
38
- );
39
-
40
- await Promise.all(archives);
41
- await Promise.all(entries);
42
- };
package/helpers/index.js DELETED
@@ -1,19 +0,0 @@
1
- const ArchiveBuilder = require('./archive');
2
- const loadContent = require('./loadContent');
3
- const {
4
- appendSiblingsToContext,
5
- paginateArchiveContext,
6
- } = require('./pagination');
7
- const slug = require('./slug');
8
- const slugType = require('./slugType');
9
- const setup = require('./setup');
10
-
11
- module.exports = {
12
- ArchiveBuilder,
13
- loadContent,
14
- appendSiblingsToContext,
15
- paginateArchiveContext,
16
- setup,
17
- slug,
18
- slugType,
19
- };
@@ -1,45 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const readJsonFile = (dir, filename) => {
5
- try {
6
- const file = path.resolve(dir, filename);
7
- const buffer = fs.readFileSync(file);
8
- return JSON.parse(buffer);
9
- } catch (e) {
10
- return {};
11
- }
12
- };
13
-
14
- const reduceFileSystem = (name, next) =>
15
- fs
16
- .readdirSync(name, { withFileTypes: true })
17
- .reduce(next, {});
18
-
19
- const getJsonFileNameFromDirent = ({ name }) =>
20
- path.basename(name, '.json');
21
-
22
- const readFilePathFromDirent = ({ name }, root, next) =>
23
- next(path.join(root, name));
24
-
25
- const recurseFileSystem = (pathName) =>
26
- reduceFileSystem(pathName, (curr, dirent) =>
27
- Object.assign(curr, {
28
- [getJsonFileNameFromDirent(
29
- dirent,
30
- )]: dirent.isDirectory()
31
- ? readFilePathFromDirent(
32
- dirent,
33
- pathName,
34
- recurseFileSystem,
35
- )
36
- : readJsonFile(pathName, dirent.name),
37
- }),
38
- );
39
-
40
- recurseFileSystem.readJsonFile = readJsonFile;
41
- recurseFileSystem.reduceFileSystem = reduceFileSystem;
42
- recurseFileSystem.getJsonFileNameFromDirent = getJsonFileNameFromDirent;
43
- recurseFileSystem.readFilePathFromDirent = readFilePathFromDirent;
44
-
45
- module.exports = recurseFileSystem;
@@ -1,10 +0,0 @@
1
- module.exports = (src) => {
2
- try {
3
- if (!src) throw new Error('No theme file detected');
4
-
5
- // eslint-disable-next-line
6
- return require(src);
7
- } catch (e) {
8
- return {};
9
- }
10
- };
@@ -1,109 +0,0 @@
1
- const { get } = require('lodash');
2
-
3
- const getId = (v) => get(v, 'contentful_id');
4
-
5
- const genCursor = (a = [], i = 0) => ({
6
- isFirst: i === 0,
7
- isLast: i === a.length - 1,
8
- next: a[i + 1],
9
- prev: a[i - 1],
10
- first: a[0],
11
- last: a[a.length - 1],
12
- });
13
-
14
- const joinArchiveUrlWithPageNumber = (url, page) =>
15
- `${url}/${page}`;
16
-
17
- const getPreviousArchiveUrl = (archiveUrl, page) => {
18
- if (page === 2) return archiveUrl;
19
- if (page !== 1)
20
- return joinArchiveUrlWithPageNumber(
21
- archiveUrl,
22
- page - 1,
23
- );
24
-
25
- return null;
26
- };
27
-
28
- const getNextArchiveUrl = (
29
- archiveUrl,
30
- page,
31
- totalNumberOfPages,
32
- ) => {
33
- if (page < totalNumberOfPages)
34
- return joinArchiveUrlWithPageNumber(
35
- archiveUrl,
36
- page + 1,
37
- );
38
-
39
- return null;
40
- };
41
-
42
- const getCurrentArchiveUrl = (archiveUrl, page) =>
43
- page < 2
44
- ? archiveUrl
45
- : joinArchiveUrlWithPageNumber(archiveUrl, page);
46
-
47
- const getNumberOfPages = (
48
- entries = [],
49
- postsPerPage = 15,
50
- ) => {
51
- const len = Array.isArray(entries) ? entries.length : 0;
52
- return Math.ceil(len / postsPerPage);
53
- };
54
-
55
- const appendSiblingsToContext = (entries) =>
56
- entries.map((node, i) => {
57
- const cursor = genCursor(entries, i);
58
- const prev = getId(
59
- cursor.isFirst ? cursor.last : cursor.prev,
60
- );
61
-
62
- const next = getId(
63
- cursor.isLast ? cursor.first : cursor.next,
64
- );
65
-
66
- return {
67
- ...node,
68
- prev,
69
- next,
70
- };
71
- });
72
-
73
- const paginateArchiveContext = (entries = [], pathName) => {
74
- const postsPerPage = 15;
75
- const numPages = getNumberOfPages(entries, postsPerPage);
76
- const output = [];
77
-
78
- for (let i = 0; i < numPages; i += 1) {
79
- const page = i + 1; // always offset for pretty URLs
80
- const path = getCurrentArchiveUrl(pathName, page);
81
- const prev = getPreviousArchiveUrl(pathName, page);
82
- const next = getNextArchiveUrl(
83
- pathName,
84
- page,
85
- numPages,
86
- );
87
-
88
- output.push({
89
- limit: postsPerPage,
90
- skip: i * postsPerPage,
91
- total: numPages,
92
- pageNum: i,
93
- path,
94
- next,
95
- prev,
96
- });
97
- }
98
-
99
- return output;
100
- };
101
-
102
- module.exports = {
103
- appendSiblingsToContext,
104
- genCursor,
105
- getNextArchiveUrl,
106
- getNumberOfPages,
107
- getPreviousArchiveUrl,
108
- paginateArchiveContext,
109
- };
package/helpers/setup.js DELETED
@@ -1,60 +0,0 @@
1
- const path = require('path');
2
- const fs = require('fs');
3
- const { compact, get } = require('lodash');
4
- const loadContent = require('./loadContent');
5
- const loadTheme = require('./loadTheme');
6
-
7
- const getFile =
8
- (directory) =>
9
- (possibleFileNames = []) =>
10
- possibleFileNames.reduce((acc, curr) => {
11
- if (acc) return acc;
12
- const filename = path.resolve(directory, curr);
13
- return fs.existsSync(filename) ? filename : undefined;
14
- }, undefined);
15
-
16
- module.exports = (
17
- siteMetadata,
18
- plugins = [],
19
- workingDirection = process.cwd(),
20
- ) => {
21
- const f = getFile(workingDirection);
22
-
23
- const locale = loadContent(f(['locale', 'lang']));
24
- const theme = loadTheme(
25
- f(['theme.js', 'gatsby-theme.js', 'mui.js']),
26
- );
27
-
28
- return {
29
- siteMetadata: {
30
- appDirectory: '/app',
31
- author: '3merge',
32
- description: '',
33
- siteUrl: 'https://3merge.ca/',
34
- ...siteMetadata,
35
- },
36
- plugins: compact(
37
- [
38
- {
39
- resolve: 'gatsby-theme-q3',
40
- options: {
41
- icon: f([
42
- 'static/favicon.png',
43
- 'static/favicon.jpg',
44
- ]),
45
-
46
- brandingColor: get(
47
- theme,
48
- 'palette.primary.main',
49
- '#000',
50
- ),
51
-
52
- locale,
53
- theme,
54
- ...siteMetadata,
55
- },
56
- },
57
- ].concat(plugins),
58
- ),
59
- };
60
- };
package/helpers/slug.js DELETED
@@ -1,31 +0,0 @@
1
- const slugify = require('slugify');
2
-
3
- const getSlug = (target) => {
4
- const keys = ['slug', 'title', 'name', 'contentful_id'];
5
-
6
- let slug;
7
- let i = 0;
8
-
9
- do {
10
- const v = target[keys[i]];
11
- if (v)
12
- slug = slugify(v, {
13
- replacement: '-',
14
- remove: undefined,
15
- lower: true,
16
- strict: true,
17
- });
18
-
19
- i += 1;
20
- } while (!slug);
21
-
22
- return slug;
23
- };
24
-
25
- const getDirectoryPath = (v) => {
26
- if (typeof v !== 'string') return '/';
27
- return v.startsWith('/') ? v : `/${v}`;
28
- };
29
-
30
- module.exports = (node = {}, basepath = '/') =>
31
- [getDirectoryPath(basepath), getSlug(node)].join('/');
@@ -1,24 +0,0 @@
1
- const slug = require('./slug');
2
-
3
- module.exports = (
4
- dir,
5
- resourceName,
6
- { createFieldExtension, createTypes },
7
- ) => {
8
- // mirrors reach router prop
9
- // an unlikely name otherwise
10
- const resolverKey = 'to';
11
-
12
- createFieldExtension({
13
- name: resolverKey,
14
- extend: () => ({
15
- resolve: (source) => slug(source, dir),
16
- }),
17
- });
18
-
19
- createTypes(`
20
- type ${resourceName} implements Node {
21
- ${resolverKey}: String @${resolverKey}
22
- }
23
- `);
24
- };