diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index b40545160..000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,14 +0,0 @@
-module.exports = {
- env: {
- node: true,
- commonjs: true,
- es2021: true,
- },
- extends: 'eslint:recommended',
- ignorePatterns: ['tests/*'],
- parserOptions: {
- ecmaVersion: 12,
- sourceType: 'module',
- },
- rules: {},
-};
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..cb7ca4c7b
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+version: 2
+updates:
+ - package-ecosystem: "npm"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ time: "05:00"
+ commit-message:
+ prefix: fix
+ prefix-development: chore
+ include: scope
diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml
new file mode 100644
index 000000000..b3b01e7e0
--- /dev/null
+++ b/.github/workflows/dependabot-automerge.yml
@@ -0,0 +1,28 @@
+# **** AUTOMERGE ****
+# Merge automatically the PR that contain a minor or patch update on the dependency you define in env.DEPENDENCY
+# - Inspiration: https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/automating-dependabot-with-github-actions#enable-auto-merge-on-a-pull-request
+
+name: Dependabot auto-merge
+on: pull_request
+
+permissions:
+ pull-requests: write
+ contents: write
+
+jobs:
+ dependabot:
+ runs-on: ubuntu-latest
+ if: ${{ github.actor == 'dependabot[bot]' }}
+ steps:
+ - name: Dependabot metadata
+ id: metadata
+ uses: dependabot/fetch-metadata@v1.1.1
+ with:
+ github-token: "${{ secrets.GITHUB_TOKEN }}"
+ - name: Enable auto-merge for Dependabot PRs
+ if: ${{contains(steps.metadata.outputs.dependency-names, env.DEPENDENCY) && (steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor')}}
+ run: gh pr merge --auto --merge "$PR_URL"
+ env:
+ DEPENDENCY: "@storyblok/react"
+ PR_URL: ${{github.event.pull_request.html_url}}
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..9de2da2ba
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,33 @@
+name: Release CI
+
+on:
+ push:
+ branches: [main, feature/v4]
+ pull_request:
+ branches: [main, feature/v4]
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Setup Node
+ uses: actions/setup-node@v2
+ with:
+ node-version: "16.13.2"
+ cache: "npm"
+ - name: Install dependencies
+ run: npm ci
+ - name: Build lib
+ run: npm run build
+ - name: Jest run
+ run: npm run test:unit
+ - name: Cypress run
+ run: npm run test:e2e
+ - name: Release
+ working-directory: lib
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+ run: npx semantic-release
diff --git a/.gitignore b/.gitignore
index 622bd7234..f2704de5a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
-node_modules
-.cache/
.DS_Store
-yarn-error.log
-yarn.lock
+node_modules
+dist
+dist-v2
+lib/cypress/videos
+.next
\ No newline at end of file
diff --git a/.husky/.gitignore b/.husky/.gitignore
new file mode 100644
index 000000000..31354ec13
--- /dev/null
+++ b/.husky/.gitignore
@@ -0,0 +1 @@
+_
diff --git a/.husky/commit-msg b/.husky/commit-msg
new file mode 100644
index 000000000..2b0b740ca
--- /dev/null
+++ b/.husky/commit-msg
@@ -0,0 +1,6 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npx --no -- commitlint --edit "$1"
+# npx --no-install commitlint --edit
+
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 000000000..36af21989
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npx lint-staged
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 000000000..728a19f85
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,4 @@
+.*
+*.md
+*.json
+example
\ No newline at end of file
diff --git a/.prettierrc.js b/.prettierrc.js
deleted file mode 100644
index d05636081..000000000
--- a/.prettierrc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-module.exports = {
- endOfLine: 'lf',
- semi: true,
- singleQuote: true,
- tabWidth: 2,
- printWidth: 100,
-};
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 555597fda..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-language: node_js
-node_js:
- - 12
-after_success:
- - npx semantic-release@17
\ No newline at end of file
diff --git a/README.md b/README.md
index be830b367..1b83b3ba2 100644
--- a/README.md
+++ b/README.md
@@ -136,7 +136,7 @@ export const query = graphql`
#### 2. Listen to Storyblok Visual Editor events
-Use `useStoryblok` to get the new story every time is triggered a `change` event from the Visual Editor. You need to pass the `originalStory` as a first param. `bridgeOptions` (second param) is an optional param if you want to set the options for bridge by yourself:
+Use `useStoryblokState` to get the new story every time is triggered a `change` event from the Visual Editor. You need to pass the `originalStory` as a first param. `bridgeOptions` (second param) is an optional param if you want to set the options for bridge by yourself:
```js
import { StoryblokComponent, useStoryblokState } from "gatsby-source-storyblok"
@@ -190,11 +190,9 @@ import { storyblokEditable } from "gatsby-source-storyblok";
const Feature = ({ blok }) => {
return (
-
-
-
{blok.name}
-
{blok.description}
-
+
+
{blok.name}
+
{blok.description}
);
};
diff --git a/gatsby-node.js b/gatsby-node.js
deleted file mode 100644
index bbd04b993..000000000
--- a/gatsby-node.js
+++ /dev/null
@@ -1,145 +0,0 @@
-const StoryblokClient = require('storyblok-js-client');
-const Sync = require('./src/sync');
-const getStoryParams = require('./src/getStoryParams');
-const stringify = require('json-stringify-safe');
-const { createRemoteFileNode } = require(`gatsby-source-filesystem`);
-
-exports.sourceNodes = async function ({ actions }, options) {
- const { createNode, setPluginStatus } = actions;
- const client = new StoryblokClient(options);
-
- Sync.init({
- createNode,
- setPluginStatus,
- client,
- });
-
- const space = await Sync.getSpace();
- const languages = options.languages ? options.languages : space.language_codes;
- languages.push('');
-
- for (const language of languages) {
- await Sync.getAll('stories', {
- node: 'StoryblokEntry',
- params: getStoryParams(language, options),
- process: (item) => {
- for (var prop in item.content) {
- // eslint-disable-next-line no-prototype-builtins
- if (!item.content.hasOwnProperty(prop) || ['_editable', '_uid'].indexOf(prop) > -1) {
- continue;
- }
- const objectType = Object.prototype.toString
- .call(item.content[prop])
- .replace('[object ', '')
- .replace(']', '')
- .toLowerCase();
-
- if (['number', 'boolean', 'string'].indexOf(objectType) === -1) {
- continue;
- }
-
- const type = prop == 'component' ? '' : '_' + objectType;
-
- item['field_' + prop + type] = item.content[prop];
- }
-
- item.content = stringify(item.content);
- },
- });
- }
-
- await Sync.getAll('tags', {
- node: 'StoryblokTag',
- params: getStoryParams('', options),
- process: (item) => {
- item.id = item.name;
- },
- });
-
- if (options.includeLinks === true) {
- await Sync.getAll('links', {
- node: 'StoryblokLink',
- params: getStoryParams('', options),
- });
- }
-
- const datasources = await Sync.getAll('datasources', {
- node: 'StoryblokDatasource',
- });
-
- for (const datasource of datasources) {
- const datasourceSlug = datasource.slug;
-
- await Sync.getAll('datasource_entries', {
- node: 'StoryblokDatasourceEntry',
- params: {
- datasource: datasourceSlug,
- },
- process: (item) => {
- item.data_source_dimension = null;
- item.data_source = datasourceSlug;
- },
- });
-
- const datasourceDimensions = datasource.dimensions || [];
-
- for (const dimension of datasourceDimensions) {
- await Sync.getAll('datasource_entries', {
- node: 'StoryblokDatasourceEntry',
- params: {
- datasource: datasourceSlug,
- dimension: dimension.entry_value,
- },
- process: (item) => {
- item.data_source_dimension = dimension.entry_value;
- item.data_source = datasourceSlug;
- },
- });
- }
- }
-};
-
-exports.onCreateNode = async (
- { node, actions: { createNode }, createNodeId, getCache, cache },
- options
-) => {
- if (!options.localAssets) {
- return;
- }
-
- if (node.internal.type === 'StoryblokEntry') {
- const assetRegex = /(https:\/\/a\.storyblok\.com.+?(?:\.)(\w)*)/g;
- let imagePaths = node.content.match(assetRegex);
- if (imagePaths?.length) {
- imagePaths.forEach(async (imagePath) => {
- let fileNodeID;
-
- const mediaDataCacheKey = `sb-${imagePath}`;
- const cacheMediaData = await getCache(mediaDataCacheKey);
- const isCached = cacheMediaData && node.cv === cacheMediaData.updatedAt;
-
- if (isCached) {
- fileNodeID = cacheMediaData.fileNodeID;
- }
-
- if (!fileNodeID && imagePath) {
- const fileNode = await createRemoteFileNode({
- url: imagePath,
- parentNodeId: node.id,
- createNode,
- createNodeId,
- getCache,
- });
-
- if (fileNode.id) {
- fileNodeID = fileNode.id;
- await cache.set(mediaDataCacheKey, {
- fileNodeID,
- updatedAt: node.cv,
- });
- }
- }
- });
- }
- }
-};
diff --git a/index.js b/index.js
deleted file mode 100644
index 625c0891b..000000000
--- a/index.js
+++ /dev/null
@@ -1 +0,0 @@
-// noop
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 111b76f65..f007311ec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -43395,4 +43395,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/getStoryParams.js b/src/getStoryParams.js
deleted file mode 100644
index e5f5f38c2..000000000
--- a/src/getStoryParams.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * @method getStoryParams
- * @param {String} language 'en', 'de'
- * @param {Object} options? api options
- * @param {Array
} options.resolveRelations? resolve_relations field
- * @param {String} options.resolveLinks? can be story or url
- * @param {String} options.version? can be draft or released
- */
-const getStoryParams = function(language = '', options = {}) {
- let params = {}
-
- if (options.resolveLinks) {
- params.resolve_links = options.resolveLinks || '1'
- }
-
- if (options.resolveRelations) {
- params.resolve_relations = options.resolveRelations.join(',')
- }
-
- if (options.version) {
- params.version = options.version
- }
-
- if (language.length > 0) {
- params.language = language
- }
-
- return params
-}
-
-module.exports = getStoryParams
\ No newline at end of file
diff --git a/src/sync.js b/src/sync.js
deleted file mode 100644
index 082f5fd31..000000000
--- a/src/sync.js
+++ /dev/null
@@ -1,104 +0,0 @@
-const crypto = require('crypto');
-const stringify = require('json-stringify-safe');
-
-module.exports = {
- init({ createNode, client, setPluginStatus }) {
- setPluginStatus({ lastFetched: Date.now() });
- this.$createNode = createNode;
- this.$client = client;
- this.$cacheVersion = 0;
- },
-
- async getSpace() {
- const space = await this.getOne('space', 'spaces/me', {
- node: 'StoryblokSpace',
- });
- this.$cacheVersion = space.version;
- return space;
- },
-
- getPage(type, page, options) {
- let params = {
- per_page: 25,
- page: page,
- cv: this.$cacheVersion,
- };
- params = Object.assign({}, params, options.params);
- return this.$client.get(`cdn/${type}`, params);
- },
-
- createNode(name, item) {
- const nodeObject = this.builderNode(name, item);
-
- this.$createNode(nodeObject);
- },
-
- builderNode(name, item) {
- if (name === 'StoryblokDatasourceEntry') {
- return this.factoryDatasourceEntryNode(name, item);
- }
-
- return this.factoryDefaultNode(name, item);
- },
-
- factoryDefaultNode(name, item) {
- const lang = item.lang || 'default';
-
- return Object.assign({}, item, {
- id: `${name.toLowerCase()}-${item.id}-${lang}`,
- internalId: item.id,
- parent: null,
- children: [],
- internal: {
- type: name,
- contentDigest: crypto.createHash(`md5`).update(stringify(item)).digest(`hex`),
- },
- });
- },
-
- factoryDatasourceEntryNode(name, item) {
- const dimension = item.data_source_dimension || 'default';
- return Object.assign({}, item, {
- id: `${name.toLowerCase()}-${item.id}-${dimension}`,
- internalId: item.id,
- parent: null,
- children: [],
- internal: {
- type: name,
- contentDigest: crypto.createHash(`md5`).update(stringify(item)).digest(`hex`),
- },
- });
- },
-
- async getOne(single, type, options) {
- const resp = await this.$client.get(`cdn/${type}`, options.params);
- const item = resp.data[single];
- this.createNode(options.node, item);
- return item;
- },
-
- async getAll(type, options) {
- let page = 1;
- let res = await this.getPage(type, page, options);
- let all =
- res.data[type].constructor === Object ? Object.values(res.data[type]) : res.data[type];
- let lastPage = Math.ceil(res.total / 25);
-
- while (page < lastPage) {
- page++;
- res = await this.getPage(type, page, options);
- res.data[type].forEach((item) => {
- all.push(item);
- });
- }
-
- all.forEach((item) => {
- if (options.process) {
- options.process(item);
- }
- this.createNode(options.node, item);
- });
-
- return all;
- },
-};
diff --git a/tests/get-story-params.test.js b/tests/get-story-params.test.js
deleted file mode 100644
index 6e557a730..000000000
--- a/tests/get-story-params.test.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const getStoryParams = require('../src/getStoryParams')
-
-describe('getStoryParams() function', () => {
- test('without any argument should be return a empty object', () => {
- expect(getStoryParams()).toEqual({})
- })
-
- test('with a language and story as resolveLinks option', () => {
- const options = {
- resolveLinks: 'story'
- }
- expect(getStoryParams('en', options)).toEqual({
- language: 'en',
- resolve_links: 'story'
- })
- })
-
- test('with a language and url as resolveLinks option', () => {
- const options = {
- resolveLinks: 'url'
- }
- expect(getStoryParams('en', options)).toEqual({
- language: 'en',
- resolve_links: 'url'
- })
- })
-
- test('with a language and version option', () => {
- const options = {
- version: 'draft'
- }
- expect(getStoryParams('en', options)).toEqual({
- language: 'en',
- version: 'draft'
- })
- })
-
- test('with a language and version and resolve_relations options', () => {
- const options = {
- version: 'draft',
- resolveRelations: ['page.author', 'page.categories']
- }
- expect(getStoryParams('en', options)).toEqual({
- language: 'en',
- version: 'draft',
- resolve_relations: 'page.author,page.categories'
- })
- })
-})
diff --git a/tests/sync.test.js b/tests/sync.test.js
deleted file mode 100644
index 62080b776..000000000
--- a/tests/sync.test.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const StoryblokClient = require('storyblok-js-client')
-const Sync = require('../src/sync')
-
-test('horizontal_rule to generate hr tag', () => {
- const createNode = function(node) {
- expect(node.internalId).toBe(123)
- expect(node.id).toBe(`item-123-default`)
- }
- const setPluginStatus = function() {}
- const client = new StoryblokClient({})
-
- Sync.init({
- createNode,
- setPluginStatus,
- client
- })
-
- Sync.createNode('Item', {id: 123})
-})
\ No newline at end of file