Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: snyc changes from main #88

Merged
merged 21 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e5e3027
feat: get hash from sdk
Deepak-Kharah Jul 21, 2023
935a428
test: check set and get hash
Deepak-Kharah Jul 21, 2023
2581880
Merge remote-tracking branch 'origin/develop' into VC-170-get-hash-su…
Deepak-Kharah Jul 21, 2023
f1fc2c7
feat: live preivew hash is available in HOC
Deepak-Kharah Jul 24, 2023
b41c82c
chore: reutrn hash from config params for ssr
sairajchouhan Aug 25, 2023
a310928
chore: add tests
sairajchouhan Aug 25, 2023
b8283a6
Merge pull request #64 from contentstack/VC-233-return-hash-from-quer…
sairajchouhan Aug 25, 2023
c5f8092
chore: add workflow to update copyright date
Deepak-Kharah Aug 31, 2023
454726f
Merge pull request #65 from contentstack/CS-26246-update-copyright-on…
Deepak-Kharah Aug 31, 2023
fe1e1f4
change input from string to url params
sairajchouhan Sep 1, 2023
9c8fe23
test: fix failing tests
sairajchouhan Sep 1, 2023
a7ac83f
Merge pull request #66 from contentstack/url-paramss
sairajchouhan Sep 1, 2023
112183a
docs: add hash and setConfigFromParams to docs
Deepak-Kharah Sep 4, 2023
d0975e5
Merge pull request #56 from contentstack/VC-170-get-hash-support
Deepak-Kharah Sep 4, 2023
4540dc2
chore: update deps for node 18
Deepak-Kharah Sep 4, 2023
7139b30
Merge pull request #68 from contentstack/migrate-to-node18
Deepak-Kharah Sep 4, 2023
231f8c6
chore: update package version
Deepak-Kharah Sep 6, 2023
82f1646
Merge pull request #67 from contentstack/develop
Deepak-Kharah Sep 7, 2023
96e7a63
Merge remote-tracking branch 'origin/main' into VC-115/live-editor-su…
Deepak-Kharah Jan 9, 2024
5743018
test: fix test cases
Deepak-Kharah Jan 9, 2024
2974d51
chore: remove doc
Deepak-Kharah Jan 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/update-copyright-years-in-license-file.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Update copyright year(s) in license file

on:
schedule:
- cron: "0 3 1 1 *"
workflow_dispatch:

jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: FantasticFiasco/action-update-license-year@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ npm install @contentstack/live-preview-utils
Alternatively, if you want to include the package directly in your website HTML code, use the following command:

```html
<script src="https://unpkg.com/@contentstack/live-preview-utils@1.3.2/dist/index.js"></script>
<script src="https://unpkg.com/@contentstack/live-preview-utils@1.4.0/dist/index.js"></script>
```

# Initializing the SDK
Expand Down
69 changes: 48 additions & 21 deletions docs/live-preview-configs.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@

The init data has following structure

- [Contentstack Live Preview Utils SDK Configs](#contentstack-live-preview-utils-sdk-configs)
- [`init(config: IConfig)`](#initconfig-iconfig)
- [`enable`](#enable)
- [`ssr`](#ssr)
- [`editButton`](#editbutton)
- [`cleanCslpOnProduction`](#cleancslponproduction)
- [`stackDetails`](#stackdetails)
- [`apiKey`](#apikey)
- [`environment`](#environment)
- [`clientUrlParams`](#clienturlparams)
- [NA config](#na-config)
- [EU config](#eu-config)
- [`stackSdk`](#stacksdk)
- [`onLiveEdit(callback: () => void)`](#onliveeditcallback---void)
- [`onEntryChange(callback: () => void)`](#onentrychangecallback---void)
- [`getGatsbyDataFormat(sdkQuery: IStackSdk, prefix: string)`](#getgatsbydataformatsdkquery-istacksdk-prefix-string)
- [Contentstack Live Preview Utils SDK Configs](#contentstack-live-preview-utils-sdk-configs)
- [`init(config: IConfig)`](#initconfig-iconfig)
- [`enable`](#enable)
- [`ssr`](#ssr)
- [`editButton`](#editbutton)
- [`cleanCslpOnProduction`](#cleancslponproduction)
- [`stackDetails`](#stackdetails)
- [`apiKey`](#apikey)
- [`environment`](#environment)
- [`clientUrlParams`](#clienturlparams)
- [NA config](#na-config)
- [EU config](#eu-config)
- [`stackSdk`](#stacksdk)
- [`onLiveEdit(callback: () => void)`](#onliveeditcallback---void)
- [`onEntryChange(callback: () => void)`](#onentrychangecallback---void)
- [hash](#hash)
- [setConfigFromParams(config: ConstructorParameters\[0\])](#setconfigfromparamsconfig-constructorparameters0)
- [`getGatsbyDataFormat(sdkQuery: IStackSdk, prefix: string)`](#getgatsbydataformatsdkquery-istacksdk-prefix-string)

## `init(config: IConfig)`

Expand Down Expand Up @@ -253,11 +255,36 @@ const Footer = () => {
```

> **Note:** To make the `onEntryChange` method work similarly to the [`onLiveEdit`](#onliveeditcallback---void) method, you can utilize the optional parameter `skipInitialRender:true`. This will enable the function to only call the Contentstack API once.
>
>For example:
>```js
>onEntryChange(fetchData,{skipInitialRender:true})
>```

**For example:**

```js
onEntryChange(fetchData, { skipInitialRender: true });
```

## hash

The `hash` property returns the live preview hash of the entry. It returns an empty string if the page is not opened in live preivew pane.

> **Note:** In the SSR mode, the hash may not be populated automatically and may require you to pass it using the `setConfigFromParams()` method.

**For example:**

```js
console.log(ContentstackLivePreview.hash); // "hash"
```

## setConfigFromParams(config: ConstructorParameters<typeof URLSearchParams>[0])

The `setConfigFromParams` method allows you to set the configuration from the URL parameters. It accepts the URLSearchParams object as a parameter. This method is used in the SSR mode to set the live preview hash received from the URL.

**For example:**

```js
console.log(ContentstackLivePreview.hash); // ""
ContentstackLivePreview.setConfigFromParams(window.location.search); // https://example.com?live_preview=hash
console.log(ContentstackLivePreview.hash); // "hash"
```

## `getGatsbyDataFormat(sdkQuery: IStackSdk, prefix: string)`

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/live-preview-utils",
"version": "1.3.2",
"version": "1.4.0",
"types": "dist/src/index.d.ts",
"description": "Contentstack provides the Live Preview SDK to establish a communication channel between the various Contentstack SDKs and your website, transmitting live changes to the preview pane.",
"main": "dist/index.js",
Expand Down
72 changes: 72 additions & 0 deletions src/__test__/contentstack-live-preview-HOC.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PublicLogger } from "../utils/public-logger";
import { IInitData } from "../types/types";
import { sendPostmessageToWindow } from "./utils";
import packageJson from "../../package.json";
import Config from "../utils/configHandler";

describe("Live preview HOC Callback Pub Sub", () => {
afterEach(() => {
Expand Down Expand Up @@ -296,3 +297,74 @@ describe("Gatsby Data formatter", () => {
]);
});
});

describe("live preview hash", () => {
beforeAll(() => {
Config.reset();
});
afterEach(() => {
ContentstackLivePreview.subscribers = {};
ContentstackLivePreview.livePreview = null;
Config.reset();
});
test("should be empty by default", () => {
ContentstackLivePreview.init();

expect(ContentstackLivePreview.hash).toBe("");
});

test("should be set when client-data-send event is fired", async () => {
ContentstackLivePreview.init();
const livePreviewHash = "livePreviewHash1234";

await sendPostmessageToWindow("client-data-send", {
hash: livePreviewHash,
content_type_uid: "entryContentTypeUid",
entry_uid: "entryUid",
});

expect(ContentstackLivePreview.hash).toBe(livePreviewHash);
});

test("should be empty string before init", () => {
expect(ContentstackLivePreview.hash).toBe("");
});
});

describe("setConfigFromParams()", () => {
afterEach(() => {
ContentstackLivePreview.subscribers = {};
ContentstackLivePreview.livePreview = null;
});
test("should set hash if live_preview is present", () => {
ContentstackLivePreview.init();
const livePreviewHash = "livePreviewHash1234";

expect(ContentstackLivePreview.hash).toBe("");

ContentstackLivePreview.setConfigFromParams({
live_preview: livePreviewHash,
});

expect(ContentstackLivePreview.hash).toBe(livePreviewHash);
});

test("should throw an error if param is not an object", () => {
ContentstackLivePreview.init();

expect(() => {
// @ts-ignore
ContentstackLivePreview.setConfigFromParams("");
}).toThrowError("Live preview SDK: query param must be an object");
});

test("should set the params if it was set before initialization", () => {
const livePreviewHash = "livePreviewHash1234";

ContentstackLivePreview.setConfigFromParams({
live_preview: livePreviewHash,
});

expect(ContentstackLivePreview.hash).toBe(livePreviewHash);
});
});
21 changes: 21 additions & 0 deletions src/__test__/live-preview.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -894,3 +894,24 @@ describe("Live modes", () => {
expect(spiedVisualEditor).not.toHaveBeenCalled();
});
});

describe("live preview hash", () => {
test("should be empty by default", () => {
const livePreview = new LivePreview();

expect(livePreview.hash).toBe("");
});

test("should be set when client-data-send event is fired", async () => {
const livePreview = new LivePreview();
const livePreviewHash = "livePreviewHash1234";

await sendPostmessageToWindow("client-data-send", {
hash: livePreviewHash,
content_type_uid: "entryContentTypeUid",
entry_uid: "entryUid",
});

expect(livePreview.hash).toBe(livePreviewHash);
});
});
47 changes: 47 additions & 0 deletions src/contentstack-live-preview-HOC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export class ContentstackLivePreview {
static livePreview: LivePreview | null = null;
static userConfig: Partial<IInitData> | null = null;
static subscribers: { [uid: string]: OnEntryChangeCallback } = {};
static configs: {
params: ConstructorParameters<typeof URLSearchParams>[0];
} = {
params: {},
};

static init(
userConfig: Partial<IInitData> = getUserInitData()
Expand All @@ -34,13 +39,48 @@ export class ContentstackLivePreview {
ContentstackLivePreview.livePreview.setOnChangeCallback(
ContentstackLivePreview.publish
);

ContentstackLivePreview.livePreview.setConfigFromParams(
this.configs.params
);
this.configs.params = {};

return Promise.resolve(ContentstackLivePreview.livePreview);
}
} else {
ContentstackLivePreview.userConfig = userConfig;
}
}

/**
* It is the live preview hash.
* This hash could be used when data is fetched manually.
*/
static get hash(): string {
if (!this.livePreview) {
const urlParams = new URLSearchParams(this.configs.params);
return urlParams.get("live_preview") ?? "";
}

return this.livePreview.hash;
}

/**
* Sets the live preview hash from the query param which is
* accessible via `hash` property.
* @param params query param in an object form
*/
static setConfigFromParams(
params: ConstructorParameters<typeof URLSearchParams>[0] = {}
): void {
if (!this.livePreview) {
this.configs.params = params;
return;
}

this.livePreview.setConfigFromParams(params);
}

private static publish(): void {
Object.values<OnEntryChangeCallback>(
ContentstackLivePreview.subscribers
Expand Down Expand Up @@ -74,6 +114,13 @@ export class ContentstackLivePreview {
ContentstackLivePreview.livePreview.setOnChangeCallback(
ContentstackLivePreview.publish
);

ContentstackLivePreview.livePreview.setConfigFromParams(
this.configs.params
);

this.configs.params = {};

ContentstackLivePreview.userConfig = null;
}
const callbackUid = ContentstackLivePreview.subscribe(onChangeCallback);
Expand Down
31 changes: 31 additions & 0 deletions src/live-preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,35 @@ export default class LivePreview {
Config.set("onChange", onChangeCallback);
}

/**
* It is the live preview hash.
* This hash could be used when data is fetched manually.
*/
get hash(): string {
return Config.get().hash;
}

/**
* Sets the live preview hash from the query param which is
* accessible via `hash` property.
* @param params query param in an object form
*/
setConfigFromParams(
params: ConstructorParameters<typeof URLSearchParams>[0] = {}
): void {
if (typeof params !== "object")
throw new TypeError(
"Live preview SDK: query param must be an object"
);

const urlParams = new URLSearchParams(params);
const live_preview = urlParams.get("live_preview");

if (live_preview) {
Config.set("hash", live_preview);
}
}

private resolveIncomingMessage(
e: MessageEvent<ILivePreviewReceivePostMessages>
) {
Expand All @@ -278,6 +307,8 @@ export default class LivePreview {
const { contentTypeUid, entryUid } = config.stackDetails;
const { hash } = e.data.data;

this.setConfigFromParams({ live_preview: hash });

if (config.ssr) {
// Get the content from the server and replace the body

Expand Down
1 change: 1 addition & 0 deletions src/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export declare interface IConfig {
stackSdk: IStackSdk;
onChange: () => void;
runScriptsOnUpdate: boolean;
hash: string;
editButton: IConfigEditButton;
mode: ILivePreviewModeConfig;
}
Expand Down
1 change: 1 addition & 0 deletions src/utils/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function getDefaultConfig(): IConfig {
includeByQueryParameter: true,
},

hash: "",
mode: 1,

stackDetails: {
Expand Down