Skip to content

Commit

Permalink
New Feature: Plug-ins [BETA]
Browse files Browse the repository at this point in the history
  • Loading branch information
loeiks committed Jul 18, 2024
1 parent bd7b47e commit 1367876
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 24 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ In this file you can find what's changed in each version. (Versions with -dev, -

---

### 4.5.0

- New plug-in, sync Wix Members collection into your MongoDB databae to perform lookups easily with your own custom collections.
- Sync Wix Applications feature is in beta and might not work as expected, we are testing the feature and BUG fixes will be added soon.
- New config option `syncDatabase` to configure the database name for Wix application sync. This database name will be used when saving data from Wix apps to MongoDB.

### 4.4.0

- convertId function removed in place now we have two different functions to convert an id either to string or ObjectId.
Expand Down
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@exweiv/weiv-data",
"version": "4.4.0",
"version": "4.5.0",
"description": "Custom API Library for Wix sites to connect MongoDB. Designed to easily switch from wix-data APIs.",
"main": "./lib/index.js",
"files": [
Expand Down
3 changes: 3 additions & 0 deletions app/src/Apps/sleep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
148 changes: 148 additions & 0 deletions app/src/Apps/wix_members.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Sync eCom Orders to MongoDB with CUD Operations
import type { Document } from "mongodb";
import { kaptanLogar } from "../Errors/error_manager";
import { insert } from "../Functions/insert";
import { native } from "../Functions/native";
import { sleep } from "./sleep";

//@ts-ignore
import wixData from 'wix-data';
import { getWeivDataConfigs } from "../Config/weiv_data_config";

export async function onMemberCreated(event: Document): Promise<void> {
try {
// Wait 1s before inserting (in case of data not inserted in Wix app collection yet)
await sleep(1000);

// Get required information
const memberId = event.entity._id;
const { syncDatabase } = getWeivDataConfigs();

if (!syncDatabase) {
kaptanLogar("00024", "You didn't configure any database name to sync Wix apps data!");
}

const { readyFullData, readyPrivateData, readyPublicData } = await getMemberData(memberId);

// Insert to MongoDB (fire and forget)
Promise.all([
(await native(`${syncDatabase}/WixMembersPublicData`, true)).insertOne(readyPublicData, { retryWrites: true }),
(await native(`${syncDatabase}/WixMembersPrivateData`, true)).insertOne(readyPrivateData, { retryWrites: true }),
(await native(`${syncDatabase}/WixMembersFullData`, true)).insertOne(readyFullData, { retryWrites: true }),
]);
} catch (err) {
// Log Error (fire and forget)
insert("WeivDataWixAppsSyncLogs/WixMembers", {
message: "Member couldn't be created",
entityId: event.entity._id,
metadata: event.metadata
}, { suppressAuth: true, suppressHooks: true });

// Throw Error
kaptanLogar("00024", `Couldn't insert member when syncing: ${err}`);
}
};

export async function onMemberUpdated(event: Document): Promise<void> {
try {
// Wait 1s before update (in case of data not updated in Wix app collection yet)
await sleep(1000);

// Get required information
const memberId = event.entity._id;
const { syncDatabase } = getWeivDataConfigs();

if (!syncDatabase) {
kaptanLogar("00024", "You didn't configure any database name to sync Wix apps data!");
}

const { readyFullData, readyPrivateData, readyPublicData } = await getMemberData(memberId);
const find = { "entityId": memberId };

// Insert to MongoDB (fire and forget)
Promise.all([
(await native(`${syncDatabase}/WixMembersPublicData`, true)).updateOne(find, readyPublicData, { retryWrites: true }),
(await native(`${syncDatabase}/WixMembersPrivateData`, true)).updateOne(find, readyPrivateData, { retryWrites: true }),
(await native(`${syncDatabase}/WixMembersFullData`, true)).updateOne(find, readyFullData, { retryWrites: true }),
]);
} catch (err) {
// Log Error (fire and forget)
insert("WeivDataWixAppsSyncLogs/WixMembers", {
message: "Member couldn't be updated",
entityId: event.entity._id,
metadata: event.metadata
}, { suppressAuth: true, suppressHooks: true });

// Throw Error
kaptanLogar("00024", `Couldn't update member when syncing: ${err}`);
}
};

export async function onMemberDeleted(event: Document): Promise<void> {
try {
// Get required information
const memberId = event.metadata.entityId;
const { syncDatabase } = getWeivDataConfigs();

if (!syncDatabase) {
kaptanLogar("00024", "You didn't configure any database name to sync Wix apps data!");
}

const find = { "entityId": memberId };

// Insert to MongoDB (fire and forget)
Promise.all([
(await native(`${syncDatabase}/WixMembersPublicData`, true)).deleteMany(find, { retryWrites: true }),
(await native(`${syncDatabase}/WixMembersPrivateData`, true)).deleteMany(find, { retryWrites: true }),
(await native(`${syncDatabase}/WixMembersFullData`, true)).deleteMany(find, { retryWrites: true }),
]);
} catch (err) {
// Log Error (fire and forget)
insert("WeivDataWixAppsSyncLogs/WixMembers", {
message: "Member couldn't deleted",
entityId: event.metadata.entityId,
metadata: event.metadata
}, { suppressAuth: true, suppressHooks: true });

// Throw Error
kaptanLogar("00024", `Couldn't update member when syncing: ${err}`);
}
};

// HELPER FUNCTIONS
type SyncMemberData = {
readyPublicData: Document,
readyPrivateData: Document,
readyFullData: Document
}

async function getMemberData(memberId: string): Promise<SyncMemberData> {
try {
if (!memberId) {
kaptanLogar("00024", "Member ID is undefined when syncing WixMembers");
}

const [publicData, privateData, fullData] = await Promise.all([
wixData.get("Members/PublicData", memberId, { suppressAuth: true, suppressHooks: true }),
wixData.get("Members/PrivateMembersData", memberId, { suppressAuth: true, suppressHooks: true }),
wixData.get("Members/FullData", memberId, { suppressAuth: true, suppressHooks: true }),
]);

const readyPublicData = { ...publicData, entityId: publicData._id };
delete readyPublicData._id;

const readyPrivateData = { ...privateData, entityId: privateData._id, };
delete readyPrivateData._id;

const readyFullData = { ...fullData, entityId: fullData._id, };
delete readyFullData._id;

return {
readyPublicData,
readyPrivateData,
readyFullData
}
} catch (err) {
kaptanLogar("00024", `Couldn't get member data when syncing: ${err}`)
}
}
36 changes: 17 additions & 19 deletions app/src/Config/weiv_data_config.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
// //@ts-ignore
// import * as weivDataConfigs from '../../../../../../../../../user-code/backend/WeivData/config';
// import type { CustomOptions } from '@exweiv/weiv-data';
// import { kaptanLogar } from '../Errors/error_manager';
//@ts-ignore
import * as weivDataConfigs from '../../../../../../../../../user-code/backend/WeivData/config';
import type { CustomOptions } from '@exweiv/weiv-data';
import { kaptanLogar } from '../Errors/error_manager';

// var __weivDatasavedConfigs__: CustomOptions.WeivDataConfig = {
// _idType: "ObjectID"
// };
var __weivDatasavedConfigs__: CustomOptions.WeivDataConfig = {};

// export function getWeivDataConfigs(): CustomOptions.WeivDataConfig {
// try {
// const configs: undefined | (() => CustomOptions.WeivDataConfig) = weivDataConfigs["config"];
export function getWeivDataConfigs(): CustomOptions.WeivDataConfig {
try {
const configs: undefined | (() => CustomOptions.WeivDataConfig) = weivDataConfigs["config"];

// if (configs && Object.keys(__weivDatasavedConfigs__).length === 0) {
// const userConfig = configs();
// __weivDatasavedConfigs__ = { ...__weivDatasavedConfigs__, ...userConfig };
// }
if (configs && Object.keys(__weivDatasavedConfigs__).length === 0) {
const userConfig = configs();
__weivDatasavedConfigs__ = { ...__weivDatasavedConfigs__, ...userConfig };
}

// return __weivDatasavedConfigs__;
// } catch (err) {
// kaptanLogar("00021", `while getting configs of WeivData library, ${err}`);
// }
// }
return __weivDatasavedConfigs__;
} catch (err) {
kaptanLogar("00021", `while getting configs of WeivData library, ${err}`);
}
}
3 changes: 2 additions & 1 deletion app/src/Errors/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export const errorsList: Errors.ErrorsList = {
"00020": "Error with filtering methods, make sure you pass valid filter parameters in valid types",
"00021": "Error on WeivData config object, make sure you pass correct config object",
"00022": "Collection Manager Error",
"00023": "Aggegration Error"
"00023": "Aggegration Error",
"00024": "Wix Application Sync Error"
}

export default errorsList;
12 changes: 10 additions & 2 deletions app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ const query = (collectionId: CollectionID) => new QueryResult(collectionId);
const filter = () => new WeivDataFilter();
const _version = () => npm.version;

import { onMemberCreated, onMemberDeleted, onMemberUpdated } from "./Apps/wix_members";

const SyncWixApps = {
wixMembers: { onMemberCreated, onMemberUpdated, onMemberDeleted }
};

export {
query,
filter,
Expand Down Expand Up @@ -78,7 +84,8 @@ export {
deleteCollection,
renameCollection,
listCollections,
_version
_version,
SyncWixApps
}

export default {
Expand Down Expand Up @@ -117,5 +124,6 @@ export default {
deleteCollection,
renameCollection,
listCollections,
_version
_version,
SyncWixApps
}
89 changes: 88 additions & 1 deletion app/weivdata.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1933,7 +1933,14 @@ declare module '@exweiv/weiv-data' {
* @description
* WeivData config object with required and optional flags. For now there isn't any option to change.
*/
type WeivDataConfig = {}
type WeivDataConfig = {
/**
* @description
*
* This is the name of the database that you want to use to insert the data of Wix app collections. It can be any database you want.
*/
syncDatabase?: string
}

/**
* @description
Expand Down Expand Up @@ -2130,6 +2137,86 @@ declare module '@exweiv/weiv-data' {
* This error is related with .aggregate function in WeivData.
*/
"00023": "Aggegration Error"

/**
* @description
*
* First of all Wix apps are firing events delayed time to time, and even if it's very rare you may have problems with events. This is how Wix app collections works right now.
* For example, after you update a product the update event may run after 5 minutes. Yes it can be delayed that long time, and only thing you can do is contact Wix support and report this issue.
*
* If there is an error with sync operation you will see all logs in a custom database called WeivDataWixAppsSyncLogs in this database you will see collections for each Wix application and logs with required information.
*
* Example data in collections:
*
* ```json
* {
* "message": "Item couldn't be updated, due to error",
* "entityId": "09b39848-a4eb-4798-bee7-d9463474f812",
* "metadata": {}
* }
* ```
*/
"00024": "Wix Application Sync Error"
}
}

/**
* @description
*
* Plugins are helper functions/features.
*/
namespace Plugins {

/**
* @description
*
* This plugin helps you to sync Wix application collections directly with your MongoDB database, in this way you can perform lookup operations easily.
*
* > Currently this feature is experimental and BUG fixes will be added in the future. And right now only available app is Wix Members.
*
* ### How it Works?
*
* For specific tasks you have pre-built functions that you can use to sync Wix app collections. For example for Wix Members you have created, updated and deleted events where you define it inside the events.js file.
* In this events.js file you will define these events but you will use pre-built functions from WeivData library to sync the data.
*
* Example code:
* ```js
* import { SyncWixApps } from '@exweiv/weiv-data';
* const { wixMembers } = SyncWixApps;
*
* export const wixMembers_onMemberCreated = (event) => wixMembers.onMemberCreated(event);
* ```
*
* In the example code above you can understand how it works with a single line of code. You can also add your own logic like this:
*
* ```js
* import { SyncWixApps } from '@exweiv/weiv-data';
* const { wixMembers } = SyncWixApps;
*
* export const wixMembers_onMemberCreated = (event) => {
* // Sync Data (no await needed because sync functions are void and doesn't return any value)
* wixMembers.onMemberCreated(event);
*
* // Your Own Logic
* }
* ```
*
* ### Logs of Sync Errors
*
* In case of an error you can find logs in `WeivDataWixAppsSyncLogs` database in your MongoDB cluster. In this database you will have multiple collections to collect logs about each individual application.
* You can find error logs and it's details there. Plugin only save unexpected error logs not any other logs.
*/
namespace SyncWixApps {
/**
* @description
*
* Includes functions to sync Wix Members collections.
*/
interface wixMembers {
onMemberCreated: Function
onMemberUpdated: Function
onMemberDeleted: Function
}
}
}
}

0 comments on commit 1367876

Please sign in to comment.