@shopnex/cj-plugin 1.0.2 → 1.0.4
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/README.md +110 -0
- package/dist/cj-settings.d.ts +9 -2
- package/dist/cj-settings.js +92 -44
- package/dist/cj-settings.js.map +1 -1
- package/dist/exports/rsc.d.ts +1 -0
- package/dist/exports/rsc.js +3 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +61 -30
- package/dist/index.js.map +1 -1
- package/dist/rsc/ApiToken.d.ts +9 -0
- package/dist/rsc/ApiToken.js +21 -0
- package/dist/rsc/ApiToken.js.map +1 -0
- package/dist/rsc/ApiToken.scss +5 -0
- package/dist/sdk/access-token.d.ts +2 -1
- package/dist/sdk/access-token.js +33 -16
- package/dist/sdk/access-token.js.map +1 -1
- package/dist/sdk/products/products.js.map +1 -1
- package/dist/service/create-order.hook.js +10 -4
- package/dist/service/create-order.hook.js.map +1 -1
- package/dist/service/sync-products.d.ts +1 -1
- package/dist/service/sync-products.js +6 -4
- package/dist/service/sync-products.js.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/util/manage-tokens.d.ts +4 -0
- package/dist/util/manage-tokens.js +41 -0
- package/dist/util/manage-tokens.js.map +1 -0
- package/package.json +1 -1
package/README.md
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# CJ Dropshipping Plugin for Payload CMS
|
2
|
+
|
3
|
+
This plugin integrates **CJ Dropshipping** into your **Payload CMS** project by:
|
4
|
+
|
5
|
+
- Adding "CJ" as a product source.
|
6
|
+
- Automatically creating CJ orders after local orders are created.
|
7
|
+
- (Optionally) generating a `cj-settings` collection for managing API credentials dynamically.
|
8
|
+
- Syncing CJ credentials on app initialization.
|
9
|
+
|
10
|
+
---
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
```bash
|
15
|
+
pnpm install @shopnex/cj-plugin
|
16
|
+
```
|
17
|
+
|
18
|
+
or
|
19
|
+
|
20
|
+
```bash
|
21
|
+
npm install @shopnex/cj-plugin
|
22
|
+
```
|
23
|
+
|
24
|
+
or
|
25
|
+
|
26
|
+
```bash
|
27
|
+
yarn add @shopnex/cj-plugin
|
28
|
+
```
|
29
|
+
|
30
|
+
---
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
Import and add the `cjPlugin` to your Payload config:
|
35
|
+
|
36
|
+
```ts
|
37
|
+
import { buildConfig } from "payload/config";
|
38
|
+
import { cjPlugin } from "@shopnex/cj-plugin";
|
39
|
+
|
40
|
+
export default buildConfig({
|
41
|
+
collections: [
|
42
|
+
// your collections
|
43
|
+
],
|
44
|
+
plugins: [
|
45
|
+
cjPlugin({
|
46
|
+
cjApiKey: "your-cj-api-key",
|
47
|
+
cjEmailAddress: "your-email@example.com",
|
48
|
+
cjRefreshToken: "optional-refresh-token", // optional
|
49
|
+
asCollection: true, // optional - creates a cj-settings collection
|
50
|
+
collectionOverrides: {
|
51
|
+
// optional - override fields or settings for the cj-settings collection
|
52
|
+
},
|
53
|
+
}),
|
54
|
+
],
|
55
|
+
});
|
56
|
+
```
|
57
|
+
|
58
|
+
---
|
59
|
+
|
60
|
+
## Plugin Options
|
61
|
+
|
62
|
+
| Option | Type | Required | Description |
|
63
|
+
| --------------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------- |
|
64
|
+
| `cjApiKey` | `string` | Yes | Your CJ Dropshipping API key. |
|
65
|
+
| `cjEmailAddress` | `string` | Yes | Your CJ account email address. |
|
66
|
+
| `cjRefreshToken` | `string` | No | Your CJ refresh token if available. |
|
67
|
+
| `asCollection` | `boolean` | No | If true, automatically creates a `cj-settings` collection to manage CJ API credentials per tenant/shop. |
|
68
|
+
| `collectionOverrides` | `object` | No | Allows overriding the default `cj-settings` collection config (fields, hooks, etc). |
|
69
|
+
|
70
|
+
---
|
71
|
+
|
72
|
+
## What the Plugin Does
|
73
|
+
|
74
|
+
- **Modifies the `products` collection**:
|
75
|
+
- Adds a `source` option: `{ label: 'CJ', value: 'cj' }`.
|
76
|
+
- **Hooks into the `orders` collection**:
|
77
|
+
- On every new order or update, triggers the CJ order creation logic automatically.
|
78
|
+
- **Manages CJ credentials dynamically**:
|
79
|
+
- On Payload startup (`onInit`), loads all `cj-settings` documents and sets up credentials per shop.
|
80
|
+
- **Optional `cj-settings` collection**:
|
81
|
+
- If `asCollection` is true, a new `cj-settings` collection will be added automatically.
|
82
|
+
- Useful for multi-tenant setups or dynamically changing credentials.
|
83
|
+
|
84
|
+
---
|
85
|
+
|
86
|
+
## Example: cj-settings Collection
|
87
|
+
|
88
|
+
If `asCollection: true`, the following collection will be generated by default:
|
89
|
+
|
90
|
+
| Field | Type | Description |
|
91
|
+
| ---------- | -------- | --------------------------------- |
|
92
|
+
| `shop` | Relation | Reference to your shop or tenant. |
|
93
|
+
| `email` | Text | Your CJ email address. |
|
94
|
+
| `apiToken` | Text | Your CJ API key. |
|
95
|
+
|
96
|
+
You can override this structure with `collectionOverrides`.
|
97
|
+
|
98
|
+
---
|
99
|
+
|
100
|
+
## Notes
|
101
|
+
|
102
|
+
- The plugin assumes you have a `products` collection with a `source` select field already created.
|
103
|
+
- It assumes you have an `orders` collection.
|
104
|
+
- Make sure the `source` field in `products` uses a `select` type with `options` array.
|
105
|
+
|
106
|
+
---
|
107
|
+
|
108
|
+
## License
|
109
|
+
|
110
|
+
MIT
|
package/dist/cj-settings.d.ts
CHANGED
@@ -1,2 +1,9 @@
|
|
1
|
-
import type { GlobalConfig } from "payload";
|
2
|
-
export
|
1
|
+
import type { CollectionConfig, GlobalConfig } from "payload";
|
2
|
+
export type CjCollectionProps = {
|
3
|
+
overrides?: Partial<CollectionConfig>;
|
4
|
+
};
|
5
|
+
export type CjGlobalProps = {
|
6
|
+
overrides?: Partial<GlobalConfig>;
|
7
|
+
};
|
8
|
+
export declare const CjSettings: ({ overrides }: CjGlobalProps) => GlobalConfig;
|
9
|
+
export declare const CjConfigCollection: ({ overrides }: CjCollectionProps) => CollectionConfig;
|
package/dist/cj-settings.js
CHANGED
@@ -1,51 +1,99 @@
|
|
1
1
|
import { syncProducts } from "./service/sync-products";
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
2
|
+
// Shared fields definition
|
3
|
+
const sharedFields = [
|
4
|
+
// {
|
5
|
+
// label: "Credentials",
|
6
|
+
// type: "collapsible",
|
7
|
+
// fields: [
|
8
|
+
// {
|
9
|
+
// type: "row",
|
10
|
+
// fields: [
|
11
|
+
// {
|
12
|
+
// name: "emailAddress",
|
13
|
+
// type: "text",
|
14
|
+
// },
|
15
|
+
// {
|
16
|
+
// name: "apiToken",
|
17
|
+
// type: "text",
|
18
|
+
// admin: {
|
19
|
+
// components: {
|
20
|
+
// Field: "@shopnex/cj-plugin/rsc#ApiToken",
|
21
|
+
// },
|
22
|
+
// },
|
23
|
+
// },
|
24
|
+
// ],
|
25
|
+
// },
|
26
|
+
// ],
|
27
|
+
// },
|
28
|
+
// {
|
29
|
+
// label: "Logo Area POD",
|
30
|
+
// name: "pod",
|
31
|
+
// type: "upload",
|
32
|
+
// relationTo: "media",
|
33
|
+
// },
|
34
|
+
{
|
35
|
+
name: "items",
|
36
|
+
type: "array",
|
37
|
+
admin: {
|
38
|
+
description: "A list of product URLs to sync with CJ Dropshipping"
|
17
39
|
},
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
description: "A list of product URLs to sync with CJ Dropshipping"
|
23
|
-
},
|
24
|
-
fields: [
|
25
|
-
{
|
26
|
-
name: "productUrl",
|
27
|
-
type: "text"
|
28
|
-
}
|
29
|
-
],
|
30
|
-
label: "Products",
|
31
|
-
labels: {
|
32
|
-
plural: "Product URLs",
|
33
|
-
singular: "Product URL"
|
40
|
+
fields: [
|
41
|
+
{
|
42
|
+
name: "productUrl",
|
43
|
+
type: "text"
|
34
44
|
}
|
45
|
+
],
|
46
|
+
label: "Products",
|
47
|
+
labels: {
|
48
|
+
plural: "Product URLs",
|
49
|
+
singular: "Product URL"
|
35
50
|
}
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
}
|
46
|
-
|
47
|
-
|
48
|
-
|
51
|
+
}
|
52
|
+
];
|
53
|
+
// Shared hooks definition
|
54
|
+
const sharedHooks = {
|
55
|
+
afterChange: [
|
56
|
+
async ({ doc, req })=>{
|
57
|
+
const productIds = doc.items.map((item)=>{
|
58
|
+
const match = item.productUrl.match(/(?<=-p-)([0-9A-Fa-f-]+)(?=\.html)/);
|
59
|
+
return match ? match[0] : null;
|
60
|
+
});
|
61
|
+
const shopId = req.user?.shops?.[0]?.shop?.id;
|
62
|
+
await syncProducts(productIds, req.payload, shopId);
|
63
|
+
}
|
64
|
+
]
|
49
65
|
};
|
66
|
+
// Global Config
|
67
|
+
export const CjSettings = ({ overrides })=>({
|
68
|
+
slug: "cj-settings",
|
69
|
+
access: {
|
70
|
+
...overrides?.access
|
71
|
+
},
|
72
|
+
admin: {
|
73
|
+
group: "Plugins",
|
74
|
+
...overrides?.admin
|
75
|
+
},
|
76
|
+
fields: sharedFields,
|
77
|
+
hooks: sharedHooks,
|
78
|
+
label: "CJ Dropshipping",
|
79
|
+
...overrides || {}
|
80
|
+
});
|
81
|
+
export const CjConfigCollection = ({ overrides })=>({
|
82
|
+
slug: "cj-settings",
|
83
|
+
access: {
|
84
|
+
...overrides?.access
|
85
|
+
},
|
86
|
+
admin: {
|
87
|
+
group: "Plugins",
|
88
|
+
...overrides?.admin
|
89
|
+
},
|
90
|
+
fields: sharedFields,
|
91
|
+
hooks: sharedHooks,
|
92
|
+
labels: {
|
93
|
+
singular: "CJ Dropshipping",
|
94
|
+
plural: "CJ Configs"
|
95
|
+
},
|
96
|
+
...overrides || {}
|
97
|
+
});
|
50
98
|
|
51
99
|
//# sourceMappingURL=cj-settings.js.map
|
package/dist/cj-settings.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/cj-settings.ts"],"sourcesContent":["import type { GlobalConfig } from \"payload\";\
|
1
|
+
{"version":3,"sources":["../src/cj-settings.ts"],"sourcesContent":["import type { CollectionConfig, Field, GlobalConfig } from \"payload\";\nimport { syncProducts } from \"./service/sync-products\";\n\n// Collection Config\nexport type CjCollectionProps = {\n overrides?: Partial<CollectionConfig>;\n};\n\nexport type CjGlobalProps = {\n overrides?: Partial<GlobalConfig>;\n};\n\n// Shared fields definition\nconst sharedFields: Field[] = [\n // {\n // label: \"Credentials\",\n // type: \"collapsible\",\n // fields: [\n // {\n // type: \"row\",\n // fields: [\n // {\n // name: \"emailAddress\",\n // type: \"text\",\n // },\n // {\n // name: \"apiToken\",\n // type: \"text\",\n // admin: {\n // components: {\n // Field: \"@shopnex/cj-plugin/rsc#ApiToken\",\n // },\n // },\n // },\n // ],\n // },\n // ],\n // },\n // {\n // label: \"Logo Area POD\",\n // name: \"pod\",\n // type: \"upload\",\n // relationTo: \"media\",\n // },\n {\n name: \"items\",\n type: \"array\",\n admin: {\n description: \"A list of product URLs to sync with CJ Dropshipping\",\n },\n fields: [\n {\n name: \"productUrl\",\n type: \"text\",\n },\n ],\n label: \"Products\",\n labels: {\n plural: \"Product URLs\",\n singular: \"Product URL\",\n },\n },\n];\n\n// Shared hooks definition\nconst sharedHooks = {\n afterChange: [\n async ({ doc, req }) => {\n const productIds = doc.items.map((item: any) => {\n const match = item.productUrl.match(/(?<=-p-)([0-9A-Fa-f-]+)(?=\\.html)/);\n return match ? match[0] : null;\n });\n const shopId = req.user?.shops?.[0]?.shop?.id;\n await syncProducts(productIds, req.payload, shopId);\n },\n ],\n};\n\n// Global Config\nexport const CjSettings = ({ overrides }: CjGlobalProps): GlobalConfig => ({\n slug: \"cj-settings\",\n access: {\n ...overrides?.access,\n },\n admin: {\n group: \"Plugins\",\n ...overrides?.admin,\n },\n fields: sharedFields,\n hooks: sharedHooks,\n label: \"CJ Dropshipping\",\n ...(overrides || {}),\n});\n\nexport const CjConfigCollection = ({ overrides }: CjCollectionProps): CollectionConfig => ({\n slug: \"cj-settings\",\n access: {\n ...overrides?.access,\n },\n admin: {\n group: \"Plugins\",\n ...overrides?.admin,\n },\n fields: sharedFields,\n hooks: sharedHooks,\n labels: {\n singular: \"CJ Dropshipping\",\n plural: \"CJ Configs\",\n },\n ...(overrides || {}),\n});\n"],"names":["syncProducts","sharedFields","name","type","admin","description","fields","label","labels","plural","singular","sharedHooks","afterChange","doc","req","productIds","items","map","item","match","productUrl","shopId","user","shops","shop","id","payload","CjSettings","overrides","slug","access","group","hooks","CjConfigCollection"],"mappings":"AACA,SAASA,YAAY,QAAQ,0BAA0B;AAWvD,2BAA2B;AAC3B,MAAMC,eAAwB;IAC1B,IAAI;IACJ,4BAA4B;IAC5B,2BAA2B;IAC3B,gBAAgB;IAChB,YAAY;IACZ,2BAA2B;IAC3B,wBAAwB;IACxB,oBAAoB;IACpB,4CAA4C;IAC5C,oCAAoC;IACpC,qBAAqB;IACrB,oBAAoB;IACpB,wCAAwC;IACxC,oCAAoC;IACpC,+BAA+B;IAC/B,wCAAwC;IACxC,wEAAwE;IACxE,6BAA6B;IAC7B,yBAAyB;IACzB,qBAAqB;IACrB,iBAAiB;IACjB,aAAa;IACb,SAAS;IACT,KAAK;IACL,IAAI;IACJ,8BAA8B;IAC9B,mBAAmB;IACnB,sBAAsB;IACtB,2BAA2B;IAC3B,KAAK;IACL;QACIC,MAAM;QACNC,MAAM;QACNC,OAAO;YACHC,aAAa;QACjB;QACAC,QAAQ;YACJ;gBACIJ,MAAM;gBACNC,MAAM;YACV;SACH;QACDI,OAAO;QACPC,QAAQ;YACJC,QAAQ;YACRC,UAAU;QACd;IACJ;CACH;AAED,0BAA0B;AAC1B,MAAMC,cAAc;IAChBC,aAAa;QACT,OAAO,EAAEC,GAAG,EAAEC,GAAG,EAAE;YACf,MAAMC,aAAaF,IAAIG,KAAK,CAACC,GAAG,CAAC,CAACC;gBAC9B,MAAMC,QAAQD,KAAKE,UAAU,CAACD,KAAK,CAAC;gBACpC,OAAOA,QAAQA,KAAK,CAAC,EAAE,GAAG;YAC9B;YACA,MAAME,SAASP,IAAIQ,IAAI,EAAEC,OAAO,CAAC,EAAE,EAAEC,MAAMC;YAC3C,MAAMzB,aAAae,YAAYD,IAAIY,OAAO,EAAEL;QAChD;KACH;AACL;AAEA,gBAAgB;AAChB,OAAO,MAAMM,aAAa,CAAC,EAAEC,SAAS,EAAiB,GAAoB,CAAA;QACvEC,MAAM;QACNC,QAAQ;YACJ,GAAGF,WAAWE,MAAM;QACxB;QACA1B,OAAO;YACH2B,OAAO;YACP,GAAGH,WAAWxB,KAAK;QACvB;QACAE,QAAQL;QACR+B,OAAOrB;QACPJ,OAAO;QACP,GAAIqB,aAAa,CAAC,CAAC;IACvB,CAAA,EAAG;AAEH,OAAO,MAAMK,qBAAqB,CAAC,EAAEL,SAAS,EAAqB,GAAwB,CAAA;QACvFC,MAAM;QACNC,QAAQ;YACJ,GAAGF,WAAWE,MAAM;QACxB;QACA1B,OAAO;YACH2B,OAAO;YACP,GAAGH,WAAWxB,KAAK;QACvB;QACAE,QAAQL;QACR+B,OAAOrB;QACPH,QAAQ;YACJE,UAAU;YACVD,QAAQ;QACZ;QACA,GAAImB,aAAa,CAAC,CAAC;IACvB,CAAA,EAAG"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export { ApiToken } from "../rsc/ApiToken";
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../src/exports/rsc.ts"],"sourcesContent":["export { ApiToken } from \"../rsc/ApiToken\";\n"],"names":["ApiToken"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,kBAAkB"}
|
package/dist/index.d.ts
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
import type { Config } from
|
1
|
+
import type { Config } from "payload";
|
2
|
+
import { CjCollectionProps, CjGlobalProps } from "./cj-settings";
|
2
3
|
interface PluginOptions {
|
4
|
+
isEnabled?: boolean;
|
3
5
|
cjApiKey: string;
|
4
6
|
cjEmailAddress: string;
|
5
7
|
cjRefreshToken?: string;
|
8
|
+
isGlobal?: boolean;
|
9
|
+
collectionOverrides?: CjCollectionProps["overrides"];
|
10
|
+
globalOverrides?: CjGlobalProps["overrides"];
|
11
|
+
orderCollectionSlug?: string;
|
6
12
|
}
|
7
13
|
export declare const cjPlugin: (pluginOptions: PluginOptions) => (config: Config) => Config;
|
8
14
|
export {};
|
package/dist/index.js
CHANGED
@@ -1,36 +1,67 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
const updateCollection = (collection)=>{
|
5
|
-
if (collection.slug === 'orders') {
|
6
|
-
return {
|
7
|
-
...collection,
|
8
|
-
hooks: {
|
9
|
-
...collection.hooks,
|
10
|
-
afterChange: [
|
11
|
-
...collection.hooks?.afterChange || [],
|
12
|
-
createOrderHook
|
13
|
-
]
|
14
|
-
}
|
15
|
-
};
|
16
|
-
}
|
17
|
-
return collection;
|
18
|
-
};
|
1
|
+
import { setTenantCredentials } from "./sdk/access-token";
|
2
|
+
import { createOrderHook } from "./service/create-order.hook";
|
3
|
+
import { CjConfigCollection, CjSettings } from "./cj-settings";
|
19
4
|
export const cjPlugin = (pluginOptions)=>(config)=>{
|
20
|
-
const
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
5
|
+
const isGlobal = pluginOptions.isGlobal ?? true;
|
6
|
+
const isEnabled = pluginOptions.isEnabled ?? true;
|
7
|
+
const ordersCollection = config.collections?.find((collection)=>collection.slug === (pluginOptions.orderCollectionSlug || "orders"));
|
8
|
+
if (!ordersCollection) {
|
9
|
+
throw new Error("No orders collection found");
|
10
|
+
}
|
11
|
+
if (!ordersCollection.hooks) {
|
12
|
+
ordersCollection.hooks = {};
|
13
|
+
}
|
14
|
+
if (!ordersCollection.hooks?.afterChange?.length) {
|
15
|
+
ordersCollection.hooks.afterChange = [];
|
16
|
+
}
|
17
|
+
if (isGlobal) {
|
18
|
+
config.globals?.push(CjSettings({
|
19
|
+
overrides: pluginOptions.globalOverrides
|
20
|
+
}));
|
21
|
+
} else {
|
22
|
+
config.collections?.push(CjConfigCollection({
|
23
|
+
overrides: pluginOptions.collectionOverrides
|
24
|
+
}));
|
25
|
+
}
|
26
|
+
const productCollection = config.collections?.find((collection)=>collection.slug === "products");
|
27
|
+
const sourceField = productCollection?.fields?.find((field)=>field.name === "source");
|
28
|
+
sourceField.options.push({
|
29
|
+
label: "CJ",
|
30
|
+
value: "cj"
|
25
31
|
});
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
if (!isEnabled) {
|
33
|
+
return config;
|
34
|
+
}
|
35
|
+
if (ordersCollection.hooks?.afterChange) {
|
36
|
+
ordersCollection.hooks.afterChange.push(createOrderHook);
|
37
|
+
}
|
38
|
+
const incomingOnInit = config.onInit;
|
39
|
+
config.onInit = async (payload)=>{
|
40
|
+
if (incomingOnInit) {
|
41
|
+
await incomingOnInit(payload);
|
42
|
+
}
|
43
|
+
const cjSettingsDocs = [];
|
44
|
+
if (isGlobal) {
|
45
|
+
setTenantCredentials("1", {
|
46
|
+
emailAddress: pluginOptions.cjEmailAddress,
|
47
|
+
password: pluginOptions.cjApiKey,
|
48
|
+
refreshToken: pluginOptions.cjRefreshToken
|
49
|
+
});
|
50
|
+
return;
|
51
|
+
} else {
|
52
|
+
const cjSettings = await payload.find({
|
53
|
+
collection: "cj-settings"
|
54
|
+
});
|
55
|
+
cjSettingsDocs.push(...cjSettings?.docs);
|
56
|
+
}
|
57
|
+
cjSettingsDocs.forEach((config)=>{
|
58
|
+
setTenantCredentials(config?.shop?.slug || "1", {
|
59
|
+
emailAddress: config.email,
|
60
|
+
password: config.apiToken
|
61
|
+
});
|
62
|
+
});
|
33
63
|
};
|
64
|
+
return config;
|
34
65
|
};
|
35
66
|
|
36
67
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Config, SelectField } from \"payload\";\nimport { setTenantCredentials } from \"./sdk/access-token\";\nimport { createOrderHook } from \"./service/create-order.hook\";\nimport { CjCollectionProps, CjConfigCollection, CjGlobalProps, CjSettings } from \"./cj-settings\";\n\ninterface PluginOptions {\n isEnabled?: boolean;\n cjApiKey: string;\n cjEmailAddress: string;\n cjRefreshToken?: string;\n isGlobal?: boolean;\n collectionOverrides?: CjCollectionProps[\"overrides\"];\n globalOverrides?: CjGlobalProps[\"overrides\"];\n orderCollectionSlug?: string;\n}\n\nexport const cjPlugin =\n (pluginOptions: PluginOptions) =>\n (config: Config): Config => {\n const isGlobal = pluginOptions.isGlobal ?? true;\n\n const isEnabled = pluginOptions.isEnabled ?? true;\n\n const ordersCollection = config.collections?.find(\n (collection) => collection.slug === (pluginOptions.orderCollectionSlug || \"orders\"),\n );\n\n if (!ordersCollection) {\n throw new Error(\"No orders collection found\");\n }\n\n if (!ordersCollection.hooks) {\n ordersCollection.hooks = {};\n }\n\n if (!ordersCollection.hooks?.afterChange?.length) {\n ordersCollection.hooks.afterChange = [];\n }\n\n if (isGlobal) {\n config.globals?.push(CjSettings({ overrides: pluginOptions.globalOverrides }));\n } else {\n config.collections?.push(\n CjConfigCollection({ overrides: pluginOptions.collectionOverrides }),\n );\n }\n const productCollection = config.collections?.find(\n (collection) => collection.slug === \"products\",\n );\n\n const sourceField = productCollection?.fields?.find(\n (field) => (field as SelectField).name === \"source\",\n ) as SelectField;\n\n sourceField.options.push({\n label: \"CJ\",\n value: \"cj\",\n });\n\n if (!isEnabled) {\n return config;\n }\n if (ordersCollection.hooks?.afterChange) {\n ordersCollection.hooks.afterChange.push(createOrderHook);\n }\n\n const incomingOnInit = config.onInit;\n\n config.onInit = async (payload) => {\n if (incomingOnInit) {\n await incomingOnInit(payload);\n }\n\n const cjSettingsDocs: any = [];\n\n if (isGlobal) {\n setTenantCredentials(\"1\", {\n emailAddress: pluginOptions.cjEmailAddress,\n password: pluginOptions.cjApiKey,\n refreshToken: pluginOptions.cjRefreshToken,\n });\n return;\n } else {\n const cjSettings = await payload.find({\n collection: \"cj-settings\",\n });\n\n cjSettingsDocs.push(...cjSettings?.docs);\n }\n\n cjSettingsDocs.forEach((config: any) => {\n setTenantCredentials(config?.shop?.slug || \"1\", {\n emailAddress: config.email,\n password: config.apiToken,\n });\n });\n };\n\n return config;\n };\n"],"names":["setTenantCredentials","createOrderHook","CjConfigCollection","CjSettings","cjPlugin","pluginOptions","config","isGlobal","isEnabled","ordersCollection","collections","find","collection","slug","orderCollectionSlug","Error","hooks","afterChange","length","globals","push","overrides","globalOverrides","collectionOverrides","productCollection","sourceField","fields","field","name","options","label","value","incomingOnInit","onInit","payload","cjSettingsDocs","emailAddress","cjEmailAddress","password","cjApiKey","refreshToken","cjRefreshToken","cjSettings","docs","forEach","shop","email","apiToken"],"mappings":"AACA,SAASA,oBAAoB,QAAQ,qBAAqB;AAC1D,SAASC,eAAe,QAAQ,8BAA8B;AAC9D,SAA4BC,kBAAkB,EAAiBC,UAAU,QAAQ,gBAAgB;AAajG,OAAO,MAAMC,WACT,CAACC,gBACD,CAACC;QACG,MAAMC,WAAWF,cAAcE,QAAQ,IAAI;QAE3C,MAAMC,YAAYH,cAAcG,SAAS,IAAI;QAE7C,MAAMC,mBAAmBH,OAAOI,WAAW,EAAEC,KACzC,CAACC,aAAeA,WAAWC,IAAI,KAAMR,CAAAA,cAAcS,mBAAmB,IAAI,QAAO;QAGrF,IAAI,CAACL,kBAAkB;YACnB,MAAM,IAAIM,MAAM;QACpB;QAEA,IAAI,CAACN,iBAAiBO,KAAK,EAAE;YACzBP,iBAAiBO,KAAK,GAAG,CAAC;QAC9B;QAEA,IAAI,CAACP,iBAAiBO,KAAK,EAAEC,aAAaC,QAAQ;YAC9CT,iBAAiBO,KAAK,CAACC,WAAW,GAAG,EAAE;QAC3C;QAEA,IAAIV,UAAU;YACVD,OAAOa,OAAO,EAAEC,KAAKjB,WAAW;gBAAEkB,WAAWhB,cAAciB,eAAe;YAAC;QAC/E,OAAO;YACHhB,OAAOI,WAAW,EAAEU,KAChBlB,mBAAmB;gBAAEmB,WAAWhB,cAAckB,mBAAmB;YAAC;QAE1E;QACA,MAAMC,oBAAoBlB,OAAOI,WAAW,EAAEC,KAC1C,CAACC,aAAeA,WAAWC,IAAI,KAAK;QAGxC,MAAMY,cAAcD,mBAAmBE,QAAQf,KAC3C,CAACgB,QAAU,AAACA,MAAsBC,IAAI,KAAK;QAG/CH,YAAYI,OAAO,CAACT,IAAI,CAAC;YACrBU,OAAO;YACPC,OAAO;QACX;QAEA,IAAI,CAACvB,WAAW;YACZ,OAAOF;QACX;QACA,IAAIG,iBAAiBO,KAAK,EAAEC,aAAa;YACrCR,iBAAiBO,KAAK,CAACC,WAAW,CAACG,IAAI,CAACnB;QAC5C;QAEA,MAAM+B,iBAAiB1B,OAAO2B,MAAM;QAEpC3B,OAAO2B,MAAM,GAAG,OAAOC;YACnB,IAAIF,gBAAgB;gBAChB,MAAMA,eAAeE;YACzB;YAEA,MAAMC,iBAAsB,EAAE;YAE9B,IAAI5B,UAAU;gBACVP,qBAAqB,KAAK;oBACtBoC,cAAc/B,cAAcgC,cAAc;oBAC1CC,UAAUjC,cAAckC,QAAQ;oBAChCC,cAAcnC,cAAcoC,cAAc;gBAC9C;gBACA;YACJ,OAAO;gBACH,MAAMC,aAAa,MAAMR,QAAQvB,IAAI,CAAC;oBAClCC,YAAY;gBAChB;gBAEAuB,eAAef,IAAI,IAAIsB,YAAYC;YACvC;YAEAR,eAAeS,OAAO,CAAC,CAACtC;gBACpBN,qBAAqBM,QAAQuC,MAAMhC,QAAQ,KAAK;oBAC5CuB,cAAc9B,OAAOwC,KAAK;oBAC1BR,UAAUhC,OAAOyC,QAAQ;gBAC7B;YACJ;QACJ;QAEA,OAAOzC;IACX,EAAE"}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
"use client";
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
3
|
+
import React from "react";
|
4
|
+
import { PasswordField } from "@payloadcms/ui";
|
5
|
+
import "./ApiToken.scss";
|
6
|
+
export function ApiToken({ path, readOnly, label = "API Token" }) {
|
7
|
+
return /*#__PURE__*/ _jsx(PasswordField, {
|
8
|
+
autoComplete: "new-password",
|
9
|
+
field: {
|
10
|
+
name: "password",
|
11
|
+
label: "API Token"
|
12
|
+
},
|
13
|
+
indexPath: "",
|
14
|
+
parentPath: "",
|
15
|
+
parentSchemaPath: "",
|
16
|
+
path: path,
|
17
|
+
schemaPath: "password"
|
18
|
+
});
|
19
|
+
}
|
20
|
+
|
21
|
+
//# sourceMappingURL=ApiToken.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../src/rsc/ApiToken.tsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { PasswordField } from \"@payloadcms/ui\";\nimport \"./ApiToken.scss\";\n\ninterface ApiTokenProps {\n path: string;\n readOnly?: boolean;\n label?: string;\n}\n\nexport function ApiToken({ path, readOnly, label = \"API Token\" }: ApiTokenProps) {\n return (\n <PasswordField\n autoComplete=\"new-password\"\n field={{\n name: \"password\",\n label: \"API Token\",\n }}\n indexPath=\"\"\n parentPath=\"\"\n parentSchemaPath=\"\"\n path={path}\n schemaPath=\"password\"\n />\n );\n}\n"],"names":["React","PasswordField","ApiToken","path","readOnly","label","autoComplete","field","name","indexPath","parentPath","parentSchemaPath","schemaPath"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAQ;AAC1B,SAASC,aAAa,QAAQ,iBAAiB;AAC/C,OAAO,kBAAkB;AAQzB,OAAO,SAASC,SAAS,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,QAAQ,WAAW,EAAiB;IAC3E,qBACI,KAACJ;QACGK,cAAa;QACbC,OAAO;YACHC,MAAM;YACNH,OAAO;QACX;QACAI,WAAU;QACVC,YAAW;QACXC,kBAAiB;QACjBR,MAAMA;QACNS,YAAW;;AAGvB"}
|
@@ -4,5 +4,6 @@ type Credentials = {
|
|
4
4
|
refreshToken?: string;
|
5
5
|
};
|
6
6
|
export declare const getCurrentAccessToken: () => Promise<string>;
|
7
|
-
export declare const
|
7
|
+
export declare const setTenantCredentials: (shopId: string, creds: Credentials) => void;
|
8
|
+
export declare const getTenantAccessToken: (shopId: string) => Promise<string>;
|
8
9
|
export {};
|
package/dist/sdk/access-token.js
CHANGED
@@ -1,22 +1,39 @@
|
|
1
|
-
import * as cjSdk from
|
2
|
-
|
1
|
+
import * as cjSdk from "./cj-sdk";
|
2
|
+
const tenantCredentialsMap = new Map();
|
3
3
|
export const getCurrentAccessToken = async ()=>{
|
4
|
-
|
5
|
-
|
6
|
-
}
|
7
|
-
const { emailAddress, password, refreshToken } = credentials;
|
8
|
-
let accessToken = (await cjSdk.refreshAccessToken(refreshToken || '')).accessToken;
|
9
|
-
if (!accessToken) {
|
10
|
-
accessToken = (await cjSdk.getAccessToken(emailAddress, password)).accessToken;
|
11
|
-
}
|
4
|
+
const shopId = "1";
|
5
|
+
const accessToken = await getTenantAccessToken(shopId);
|
12
6
|
return accessToken;
|
13
7
|
};
|
14
|
-
export const
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
8
|
+
export const setTenantCredentials = (shopId, creds)=>{
|
9
|
+
tenantCredentialsMap.set(shopId, creds);
|
10
|
+
};
|
11
|
+
export const getTenantAccessToken = async (shopId)=>{
|
12
|
+
const creds = tenantCredentialsMap.get(shopId);
|
13
|
+
if (!creds?.emailAddress || !creds?.password) {
|
14
|
+
throw new Error(`Credentials for tenant ${shopId} are missing or incomplete`);
|
15
|
+
}
|
16
|
+
const { emailAddress, password, refreshToken } = creds;
|
17
|
+
let newAccessToken;
|
18
|
+
let newRefreshToken;
|
19
|
+
if (!refreshToken) {
|
20
|
+
const result = await cjSdk.getAccessToken(emailAddress, password);
|
21
|
+
newAccessToken = result.accessToken;
|
22
|
+
newRefreshToken = result.refreshToken;
|
23
|
+
tenantCredentialsMap.set(shopId, {
|
24
|
+
...creds,
|
25
|
+
refreshToken: newRefreshToken
|
26
|
+
});
|
27
|
+
} else {
|
28
|
+
const result = await cjSdk.refreshAccessToken(refreshToken);
|
29
|
+
newAccessToken = result.accessToken;
|
30
|
+
newRefreshToken = result.refreshToken;
|
31
|
+
tenantCredentialsMap.set(shopId, {
|
32
|
+
...creds,
|
33
|
+
refreshToken: newRefreshToken
|
34
|
+
});
|
35
|
+
}
|
36
|
+
return newAccessToken;
|
20
37
|
};
|
21
38
|
|
22
39
|
//# sourceMappingURL=access-token.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/sdk/access-token.ts"],"sourcesContent":["import * as cjSdk from
|
1
|
+
{"version":3,"sources":["../../src/sdk/access-token.ts"],"sourcesContent":["import * as cjSdk from \"./cj-sdk\";\n\ntype Credentials = {\n emailAddress: string;\n password: string;\n refreshToken?: string;\n};\n\nconst tenantCredentialsMap = new Map<string, Credentials>();\n\nexport const getCurrentAccessToken = async () => {\n const shopId = \"1\";\n const accessToken = await getTenantAccessToken(shopId);\n return accessToken;\n};\n\nexport const setTenantCredentials = (shopId: string, creds: Credentials) => {\n tenantCredentialsMap.set(shopId, creds);\n};\n\nexport const getTenantAccessToken = async (shopId: string) => {\n const creds = tenantCredentialsMap.get(shopId);\n\n if (!creds?.emailAddress || !creds?.password) {\n throw new Error(`Credentials for tenant ${shopId} are missing or incomplete`);\n }\n\n const { emailAddress, password, refreshToken } = creds;\n\n let newAccessToken: string;\n let newRefreshToken: string | undefined;\n\n if (!refreshToken) {\n const result = await cjSdk.getAccessToken(emailAddress, password);\n newAccessToken = result.accessToken;\n newRefreshToken = result.refreshToken;\n\n tenantCredentialsMap.set(shopId, {\n ...creds,\n refreshToken: newRefreshToken,\n });\n } else {\n const result = await cjSdk.refreshAccessToken(refreshToken);\n newAccessToken = result.accessToken;\n newRefreshToken = result.refreshToken;\n\n tenantCredentialsMap.set(shopId, {\n ...creds,\n refreshToken: newRefreshToken,\n });\n }\n\n return newAccessToken;\n};\n"],"names":["cjSdk","tenantCredentialsMap","Map","getCurrentAccessToken","shopId","accessToken","getTenantAccessToken","setTenantCredentials","creds","set","get","emailAddress","password","Error","refreshToken","newAccessToken","newRefreshToken","result","getAccessToken","refreshAccessToken"],"mappings":"AAAA,YAAYA,WAAW,WAAW;AAQlC,MAAMC,uBAAuB,IAAIC;AAEjC,OAAO,MAAMC,wBAAwB;IACjC,MAAMC,SAAS;IACf,MAAMC,cAAc,MAAMC,qBAAqBF;IAC/C,OAAOC;AACX,EAAE;AAEF,OAAO,MAAME,uBAAuB,CAACH,QAAgBI;IACjDP,qBAAqBQ,GAAG,CAACL,QAAQI;AACrC,EAAE;AAEF,OAAO,MAAMF,uBAAuB,OAAOF;IACvC,MAAMI,QAAQP,qBAAqBS,GAAG,CAACN;IAEvC,IAAI,CAACI,OAAOG,gBAAgB,CAACH,OAAOI,UAAU;QAC1C,MAAM,IAAIC,MAAM,CAAC,uBAAuB,EAAET,OAAO,0BAA0B,CAAC;IAChF;IAEA,MAAM,EAAEO,YAAY,EAAEC,QAAQ,EAAEE,YAAY,EAAE,GAAGN;IAEjD,IAAIO;IACJ,IAAIC;IAEJ,IAAI,CAACF,cAAc;QACf,MAAMG,SAAS,MAAMjB,MAAMkB,cAAc,CAACP,cAAcC;QACxDG,iBAAiBE,OAAOZ,WAAW;QACnCW,kBAAkBC,OAAOH,YAAY;QAErCb,qBAAqBQ,GAAG,CAACL,QAAQ;YAC7B,GAAGI,KAAK;YACRM,cAAcE;QAClB;IACJ,OAAO;QACH,MAAMC,SAAS,MAAMjB,MAAMmB,kBAAkB,CAACL;QAC9CC,iBAAiBE,OAAOZ,WAAW;QACnCW,kBAAkBC,OAAOH,YAAY;QAErCb,qBAAqBQ,GAAG,CAACL,QAAQ;YAC7B,GAAGI,KAAK;YACRM,cAAcE;QAClB;IACJ;IAEA,OAAOD;AACX,EAAE"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../src/sdk/products/products.ts"],"sourcesContent":["import type { APIResponse } from '../../error-types'\nimport type {\n CategoryFirstLevel,\n CategoryListResponse,\n Product,\n ProductDetails,\n ProductListResponse,\n} from './product-types.ts'\n\nimport { cjApiClient } from '../../api-client'\nimport { getCurrentAccessToken } from '../access-token'\n\nexport async function getProductCategory(\n accessToken: string,\n params: any,\n): Promise<APIResponse<CategoryFirstLevel[]>> {\n try {\n const response = await cjApiClient.get<CategoryListResponse>('/product/getCategory', {\n headers: { 'CJ-Access-Token': accessToken },\n params,\n })\n\n const data = response.data.data\n if (!data) {\n return { error: 'No categories found' }\n }\n\n return { data }\n } catch (error: any) {\n console.error(`Error fetching categories [${error.code}]: ${error.message}`)\n return { error: error.message || 'Failed to fetch categories' }\n }\n}\n\nexport async function getProductList(\n params: Record<string, any> = {},\n): Promise<APIResponse<Product[]>> {\n const defaultParams = {\n pageNum: 1,\n pageSize: 20,\n }\n const query = { ...defaultParams, ...params }\n\n try {\n const accessToken = await getCurrentAccessToken()
|
1
|
+
{"version":3,"sources":["../../../src/sdk/products/products.ts"],"sourcesContent":["import type { APIResponse } from '../../error-types'\nimport type {\n CategoryFirstLevel,\n CategoryListResponse,\n Product,\n ProductDetails,\n ProductListResponse,\n} from './product-types.ts'\n\nimport { cjApiClient } from '../../api-client'\nimport { getCurrentAccessToken } from '../access-token'\n\nexport async function getProductCategory(\n accessToken: string,\n params: any,\n): Promise<APIResponse<CategoryFirstLevel[]>> {\n try {\n const response = await cjApiClient.get<CategoryListResponse>('/product/getCategory', {\n headers: { 'CJ-Access-Token': accessToken },\n params,\n })\n\n const data = response.data.data\n if (!data) {\n return { error: 'No categories found' }\n }\n\n return { data }\n } catch (error: any) {\n console.error(`Error fetching categories [${error.code}]: ${error.message}`)\n return { error: error.message || 'Failed to fetch categories' }\n }\n}\n\nexport async function getProductList(\n params: Record<string, any> = {},\n): Promise<APIResponse<Product[]>> {\n const defaultParams = {\n pageNum: 1,\n pageSize: 20,\n }\n const query = { ...defaultParams, ...params }\n\n try {\n const accessToken = await getCurrentAccessToken();\n const response = await cjApiClient.get<ProductListResponse>(\n 'https://developers.cjdropshipping.com/api2.0/v1/product/list',\n {\n headers: {\n 'CJ-Access-Token': accessToken,\n },\n params: query,\n },\n )\n\n const data = response.data\n\n if (!data.result) {\n return { error: data.message || 'Failed to fetch product list' }\n }\n\n if (!data.data?.list) {\n return { error: 'No products found' }\n }\n\n return { data: data.data.list }\n } catch (error: any) {\n console.error(`Error fetching product list [${error.code}]: ${error.message}`)\n return { error: error.message || 'Failed to fetch product list' }\n }\n}\n\nexport async function getProductDetails(queryParams: {\n pid?: string\n productSku?: string\n variantSku?: string\n}): Promise<APIResponse<ProductDetails>> {\n const { pid, productSku, variantSku } = queryParams\n if (!pid && !productSku && !variantSku) {\n return {\n error: 'One of pid, productSku, or variantSku must be provided.',\n }\n }\n\n try {\n const accessToken = await getCurrentAccessToken()\n const response = await cjApiClient.get<{\n code: number\n data: ProductDetails\n message: string\n result: boolean\n }>('https://developers.cjdropshipping.com/api2.0/v1/product/query', {\n headers: {\n 'CJ-Access-Token': accessToken,\n },\n params: queryParams,\n })\n\n if (!response.data.result) {\n return {\n error: response.data.message || 'Failed to fetch product details',\n }\n }\n\n return { data: response.data.data }\n } catch (error: any) {\n console.error(`Error fetching product details [${error.code}]: ${error.message}`)\n return { error: error.message || 'Failed to fetch product details' }\n }\n}\n"],"names":["cjApiClient","getCurrentAccessToken","getProductCategory","accessToken","params","response","get","headers","data","error","console","code","message","getProductList","defaultParams","pageNum","pageSize","query","result","list","getProductDetails","queryParams","pid","productSku","variantSku"],"mappings":"AASA,SAASA,WAAW,QAAQ,mBAAkB;AAC9C,SAASC,qBAAqB,QAAQ,kBAAiB;AAEvD,OAAO,eAAeC,mBACpBC,WAAmB,EACnBC,MAAW;IAEX,IAAI;QACF,MAAMC,WAAW,MAAML,YAAYM,GAAG,CAAuB,wBAAwB;YACnFC,SAAS;gBAAE,mBAAmBJ;YAAY;YAC1CC;QACF;QAEA,MAAMI,OAAOH,SAASG,IAAI,CAACA,IAAI;QAC/B,IAAI,CAACA,MAAM;YACT,OAAO;gBAAEC,OAAO;YAAsB;QACxC;QAEA,OAAO;YAAED;QAAK;IAChB,EAAE,OAAOC,OAAY;QACnBC,QAAQD,KAAK,CAAC,CAAC,2BAA2B,EAAEA,MAAME,IAAI,CAAC,GAAG,EAAEF,MAAMG,OAAO,EAAE;QAC3E,OAAO;YAAEH,OAAOA,MAAMG,OAAO,IAAI;QAA6B;IAChE;AACF;AAEA,OAAO,eAAeC,eACpBT,SAA8B,CAAC,CAAC;IAEhC,MAAMU,gBAAgB;QACpBC,SAAS;QACTC,UAAU;IACZ;IACA,MAAMC,QAAQ;QAAE,GAAGH,aAAa;QAAE,GAAGV,MAAM;IAAC;IAE5C,IAAI;QACF,MAAMD,cAAc,MAAMF;QAC1B,MAAMI,WAAW,MAAML,YAAYM,GAAG,CACpC,gEACA;YACEC,SAAS;gBACP,mBAAmBJ;YACrB;YACAC,QAAQa;QACV;QAGF,MAAMT,OAAOH,SAASG,IAAI;QAE1B,IAAI,CAACA,KAAKU,MAAM,EAAE;YAChB,OAAO;gBAAET,OAAOD,KAAKI,OAAO,IAAI;YAA+B;QACjE;QAEA,IAAI,CAACJ,KAAKA,IAAI,EAAEW,MAAM;YACpB,OAAO;gBAAEV,OAAO;YAAoB;QACtC;QAEA,OAAO;YAAED,MAAMA,KAAKA,IAAI,CAACW,IAAI;QAAC;IAChC,EAAE,OAAOV,OAAY;QACnBC,QAAQD,KAAK,CAAC,CAAC,6BAA6B,EAAEA,MAAME,IAAI,CAAC,GAAG,EAAEF,MAAMG,OAAO,EAAE;QAC7E,OAAO;YAAEH,OAAOA,MAAMG,OAAO,IAAI;QAA+B;IAClE;AACF;AAEA,OAAO,eAAeQ,kBAAkBC,WAIvC;IACC,MAAM,EAAEC,GAAG,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGH;IACxC,IAAI,CAACC,OAAO,CAACC,cAAc,CAACC,YAAY;QACtC,OAAO;YACLf,OAAO;QACT;IACF;IAEA,IAAI;QACF,MAAMN,cAAc,MAAMF;QAC1B,MAAMI,WAAW,MAAML,YAAYM,GAAG,CAKnC,iEAAiE;YAClEC,SAAS;gBACP,mBAAmBJ;YACrB;YACAC,QAAQiB;QACV;QAEA,IAAI,CAAChB,SAASG,IAAI,CAACU,MAAM,EAAE;YACzB,OAAO;gBACLT,OAAOJ,SAASG,IAAI,CAACI,OAAO,IAAI;YAClC;QACF;QAEA,OAAO;YAAEJ,MAAMH,SAASG,IAAI,CAACA,IAAI;QAAC;IACpC,EAAE,OAAOC,OAAY;QACnBC,QAAQD,KAAK,CAAC,CAAC,gCAAgC,EAAEA,MAAME,IAAI,CAAC,GAAG,EAAEF,MAAMG,OAAO,EAAE;QAChF,OAAO;YAAEH,OAAOA,MAAMG,OAAO,IAAI;QAAkC;IACrE;AACF"}
|
@@ -4,14 +4,20 @@ export const createOrderHook = async ({ doc, req })=>{
|
|
4
4
|
return;
|
5
5
|
}
|
6
6
|
const payload = req.payload;
|
7
|
-
const cjSettings = await payload.
|
8
|
-
|
7
|
+
const cjSettings = await payload.find({
|
8
|
+
collection: "cj-settings",
|
9
|
+
where: {
|
10
|
+
shop: {
|
11
|
+
equals: doc.shopId
|
12
|
+
}
|
13
|
+
}
|
9
14
|
});
|
10
|
-
const
|
15
|
+
const cjConfig = cjSettings?.docs[0];
|
16
|
+
const podProperties = cjConfig?.pod?.url ? [
|
11
17
|
{
|
12
18
|
areaName: "LogoArea",
|
13
19
|
links: [
|
14
|
-
|
20
|
+
cjConfig?.pod?.url
|
15
21
|
],
|
16
22
|
type: "1",
|
17
23
|
layer: []
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/service/create-order.hook.ts"],"sourcesContent":["import type { BasePayload, CollectionAfterChangeHook, Document } from \"payload\";\n\nimport * as cjSdk from \"../sdk/cj-sdk\";\n\nexport interface Orders extends Document {\n id: string;\n items: Array<{\n productUrl: string;\n quantity: number;\n variant: {\n variantId: string;\n };\n }>;\n}\n\nexport const createOrderHook: CollectionAfterChangeHook<Orders> = async ({ doc, req }) => {\n if (doc.orderStatus !== \"processing\") {\n return;\n }\n const payload: BasePayload = req.payload;\n const cjSettings
|
1
|
+
{"version":3,"sources":["../../src/service/create-order.hook.ts"],"sourcesContent":["import type { BasePayload, CollectionAfterChangeHook, Document } from \"payload\";\n\nimport * as cjSdk from \"../sdk/cj-sdk\";\n\nexport interface Orders extends Document {\n id: string;\n items: Array<{\n productUrl: string;\n quantity: number;\n variant: {\n variantId: string;\n };\n }>;\n}\n\nexport const createOrderHook: CollectionAfterChangeHook<Orders> = async ({ doc, req }) => {\n if (doc.orderStatus !== \"processing\") {\n return;\n }\n const payload: BasePayload = req.payload;\n const cjSettings = await payload.find({\n collection: \"cj-settings\",\n where: {\n shop: {\n equals: doc.shopId,\n },\n },\n });\n const cjConfig: any = cjSettings?.docs[0];\n const podProperties = cjConfig?.pod?.url\n ? [\n {\n areaName: \"LogoArea\",\n links: [cjConfig?.pod?.url],\n type: \"1\",\n layer: [],\n },\n ]\n : [];\n const result = await cjSdk.createOrder({\n consigneeID: doc.billingAddress?.name || \"\",\n email: doc.billingAddress?.email || \"\",\n fromCountryCode: \"CN\",\n houseNumber: doc.shippingAddress?.address?.line2 || \"\",\n iossType: 1,\n logisticName: \"CJPacket Liquid US\",\n orderNumber: doc.orderId,\n payType: 2,\n products: doc.items.map((item) => ({\n quantity: item.quantity,\n vid: item.variant.variantId,\n })),\n podProperties,\n remark: \"\",\n shippingAddress: doc.shippingAddress?.address?.line1 || \"\",\n shippingAddress2: doc.shippingAddress?.address?.line2 || \"\",\n shippingCity: doc.shippingAddress?.address?.city || \"\",\n shippingCountry: doc.shippingAddress?.address?.country || \"\",\n shippingCountryCode: doc.shippingAddress?.address?.country || \"\",\n shippingCounty: doc.shippingAddress?.address?.city || \"\",\n shippingCustomerName: doc.shippingAddress?.name || \"\",\n shippingPhone: doc.shippingAddress?.phone || \"+9999999999\",\n shippingProvince: doc.shippingAddress?.address?.state || \"\",\n shippingZip: doc.shippingAddress?.address?.postal_code || \"\",\n taxId: \"\",\n });\n\n const orderResult = await payload.update({\n collection: \"orders\",\n data: {\n orderStatus: \"shipped\",\n },\n where: {\n id: {\n equals: doc.orderId,\n },\n },\n });\n\n return {\n cjResult: result,\n orderResult,\n };\n};\n"],"names":["cjSdk","createOrderHook","doc","req","orderStatus","payload","cjSettings","find","collection","where","shop","equals","shopId","cjConfig","docs","podProperties","pod","url","areaName","links","type","layer","result","createOrder","consigneeID","billingAddress","name","email","fromCountryCode","houseNumber","shippingAddress","address","line2","iossType","logisticName","orderNumber","orderId","payType","products","items","map","item","quantity","vid","variant","variantId","remark","line1","shippingAddress2","shippingCity","city","shippingCountry","country","shippingCountryCode","shippingCounty","shippingCustomerName","shippingPhone","phone","shippingProvince","state","shippingZip","postal_code","taxId","orderResult","update","data","id","cjResult"],"mappings":"AAEA,YAAYA,WAAW,gBAAgB;AAavC,OAAO,MAAMC,kBAAqD,OAAO,EAAEC,GAAG,EAAEC,GAAG,EAAE;IACjF,IAAID,IAAIE,WAAW,KAAK,cAAc;QAClC;IACJ;IACA,MAAMC,UAAuBF,IAAIE,OAAO;IACxC,MAAMC,aAAa,MAAMD,QAAQE,IAAI,CAAC;QAClCC,YAAY;QACZC,OAAO;YACHC,MAAM;gBACFC,QAAQT,IAAIU,MAAM;YACtB;QACJ;IACJ;IACA,MAAMC,WAAgBP,YAAYQ,IAAI,CAAC,EAAE;IACzC,MAAMC,gBAAgBF,UAAUG,KAAKC,MAC/B;QACI;YACIC,UAAU;YACVC,OAAO;gBAACN,UAAUG,KAAKC;aAAI;YAC3BG,MAAM;YACNC,OAAO,EAAE;QACb;KACH,GACD,EAAE;IACR,MAAMC,SAAS,MAAMtB,MAAMuB,WAAW,CAAC;QACnCC,aAAatB,IAAIuB,cAAc,EAAEC,QAAQ;QACzCC,OAAOzB,IAAIuB,cAAc,EAAEE,SAAS;QACpCC,iBAAiB;QACjBC,aAAa3B,IAAI4B,eAAe,EAAEC,SAASC,SAAS;QACpDC,UAAU;QACVC,cAAc;QACdC,aAAajC,IAAIkC,OAAO;QACxBC,SAAS;QACTC,UAAUpC,IAAIqC,KAAK,CAACC,GAAG,CAAC,CAACC,OAAU,CAAA;gBAC/BC,UAAUD,KAAKC,QAAQ;gBACvBC,KAAKF,KAAKG,OAAO,CAACC,SAAS;YAC/B,CAAA;QACA9B;QACA+B,QAAQ;QACRhB,iBAAiB5B,IAAI4B,eAAe,EAAEC,SAASgB,SAAS;QACxDC,kBAAkB9C,IAAI4B,eAAe,EAAEC,SAASC,SAAS;QACzDiB,cAAc/C,IAAI4B,eAAe,EAAEC,SAASmB,QAAQ;QACpDC,iBAAiBjD,IAAI4B,eAAe,EAAEC,SAASqB,WAAW;QAC1DC,qBAAqBnD,IAAI4B,eAAe,EAAEC,SAASqB,WAAW;QAC9DE,gBAAgBpD,IAAI4B,eAAe,EAAEC,SAASmB,QAAQ;QACtDK,sBAAsBrD,IAAI4B,eAAe,EAAEJ,QAAQ;QACnD8B,eAAetD,IAAI4B,eAAe,EAAE2B,SAAS;QAC7CC,kBAAkBxD,IAAI4B,eAAe,EAAEC,SAAS4B,SAAS;QACzDC,aAAa1D,IAAI4B,eAAe,EAAEC,SAAS8B,eAAe;QAC1DC,OAAO;IACX;IAEA,MAAMC,cAAc,MAAM1D,QAAQ2D,MAAM,CAAC;QACrCxD,YAAY;QACZyD,MAAM;YACF7D,aAAa;QACjB;QACAK,OAAO;YACHyD,IAAI;gBACAvD,QAAQT,IAAIkC,OAAO;YACvB;QACJ;IACJ;IAEA,OAAO;QACH+B,UAAU7C;QACVyC;IACJ;AACJ,EAAE"}
|
@@ -1,4 +1,4 @@
|
|
1
1
|
import type { BasePayload } from "payload";
|
2
2
|
import type { ProductDetails } from "../sdk/products/product-types";
|
3
3
|
export declare const fetchExchangeRates: () => Promise<any>;
|
4
|
-
export declare const syncProducts: (productIds: string[], payload: BasePayload) => Promise<ProductDetails[]>;
|
4
|
+
export declare const syncProducts: (productIds: string[], payload: BasePayload, shopId?: string) => Promise<ProductDetails[]>;
|
@@ -77,6 +77,7 @@ function mapMockProductToSchema(product, editorConfig, rate, payload) {
|
|
77
77
|
html: product.description || "",
|
78
78
|
JSDOM
|
79
79
|
}),
|
80
|
+
source: "cj",
|
80
81
|
pid: product.pid,
|
81
82
|
title: product.productNameEn,
|
82
83
|
variants: product.variants?.map((variant)=>({
|
@@ -96,7 +97,7 @@ const findProductById = async (productId)=>{
|
|
96
97
|
});
|
97
98
|
return result.data;
|
98
99
|
};
|
99
|
-
const createOrUpdateProduct = async (product, payload)=>{
|
100
|
+
const createOrUpdateProduct = async (product, payload, shopId)=>{
|
100
101
|
const { totalDocs } = await payload.count({
|
101
102
|
collection: "products",
|
102
103
|
where: {
|
@@ -109,7 +110,8 @@ const createOrUpdateProduct = async (product, payload)=>{
|
|
109
110
|
return payload.create({
|
110
111
|
collection: "products",
|
111
112
|
data: {
|
112
|
-
...product
|
113
|
+
...product,
|
114
|
+
shop: shopId
|
113
115
|
}
|
114
116
|
});
|
115
117
|
}
|
@@ -119,7 +121,7 @@ export const fetchExchangeRates = async ()=>{
|
|
119
121
|
const data = await response.json();
|
120
122
|
return data;
|
121
123
|
};
|
122
|
-
export const syncProducts = async (productIds, payload)=>{
|
124
|
+
export const syncProducts = async (productIds, payload, shopId)=>{
|
123
125
|
const exchangeRates = await fetchExchangeRates();
|
124
126
|
const storeSettings = await payload.findGlobal({
|
125
127
|
slug: "store-settings"
|
@@ -140,7 +142,7 @@ export const syncProducts = async (productIds, payload)=>{
|
|
140
142
|
const mappedProducts = products.map((product)=>{
|
141
143
|
return mapMockProductToSchema(product, editorConfig, rate, payload);
|
142
144
|
});
|
143
|
-
await Promise.all(mappedProducts.map((product)=>createOrUpdateProduct(product, payload)));
|
145
|
+
await Promise.all(mappedProducts.map((product)=>createOrUpdateProduct(product, payload, shopId)));
|
144
146
|
return products;
|
145
147
|
};
|
146
148
|
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/service/sync-products.ts"],"sourcesContent":["import type { DefaultNodeTypes, TypedEditorState } from \"@payloadcms/richtext-lexical\";\nimport type { BasePayload } from \"payload\";\n\nimport { convertHTMLToLexical, editorConfigFactory } from \"@payloadcms/richtext-lexical\";\nimport decimal from \"decimal.js\";\nimport { JSDOM } from \"jsdom\";\n\nimport type { ProductDetails } from \"../sdk/products/product-types\";\n\nimport * as cjSdk from \"../sdk/cj-sdk\";\nimport path, { dirname, join } from \"path\";\nimport fs from \"fs\";\nimport { promisify } from \"util\";\nimport { pipeline } from \"stream\";\nimport { writeFile } from \"fs/promises\";\nimport { fileURLToPath } from \"url\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst streamPipeline = promisify(pipeline);\n\ninterface Product {\n description: TypedEditorState<DefaultNodeTypes>;\n pid: string;\n title: string;\n variants?: Array<{\n imageUrl?: string;\n options?: Array<{ option: string; value: string }>;\n price?: number;\n vid: string;\n }>;\n}\n\nconst delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst download = async (uri: string, filename: string): Promise<void> => {\n try {\n const response = await fetch(uri);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch ${uri}: ${response.statusText}`);\n }\n\n const contentType = response.headers.get(\"content-type\");\n const contentLength = response.headers.get(\"content-length\");\n\n console.log(\"content-type:\", contentType);\n console.log(\"content-length:\", contentLength);\n\n const buffer = Buffer.from(await response.arrayBuffer());\n\n await writeFile(filename, buffer);\n\n console.log(\"Download complete:\", filename);\n } catch (error) {\n console.error(\"Error downloading file:\", error);\n }\n};\n\n\nasync function uploadImageToPayload(src: string, payload: BasePayload): Promise<any | null> {\n const tempFilePath = path.join(__dirname, \"temp-image.jpg\");\n\n try {\n // Fetch the image\n const response = await fetch(src);\n if (!response.ok) throw new Error(`Failed to fetch image: ${response.statusText}`);\n\n // Stream the response body to a temporary file\n await download(src, tempFilePath);\n\n // Upload the image using Payload's Local API\n const uploadedImage = await payload.create({\n collection: \"media\",\n data: {\n alt: \"Some alt text\",\n },\n\n filePath: tempFilePath,\n });\n\n console.log(\"Uploaded media document:\", uploadedImage);\n\n // Clean up: delete the temporary file\n fs.unlink(tempFilePath, (err) => {\n if (err) console.error(\"Error deleting temporary file:\", err);\n });\n\n return {\n id: uploadedImage.id,\n alt: uploadedImage.alt || \"\",\n prefix: \"media\",\n updatedAt: uploadedImage.updatedAt,\n createdAt: uploadedImage.createdAt,\n url: uploadedImage.url,\n thumbnailURL: uploadedImage.thumbnailURL || null,\n filename: uploadedImage.filename,\n mimeType: uploadedImage.mimeType,\n filesize: uploadedImage.filesize,\n width: uploadedImage.width,\n height: uploadedImage.height,\n focalX: 50,\n focalY: 50,\n };\n } catch (error) {\n console.error(\"Error uploading image:\", error);\n }\n}\nfunction mapMockProductToSchema(\n product: ProductDetails,\n editorConfig: any,\n rate: number,\n payload: BasePayload,\n) {\n return {\n description: convertHTMLToLexical({\n editorConfig,\n html: product.description || \"\",\n JSDOM,\n // uploadImage: async (src: string) => {\n // return uploadImageToPayload(src, payload);\n // },\n }),\n pid: product.pid,\n title: product.productNameEn,\n variants: product.variants?.map((variant) => ({\n imageUrl: variant.variantImage, // Map image URL to 'id' if using media collection\n options: variant.variantKey?.split(\"-\").map((key, index) => ({\n option: index === 0 ? \"Color\" : \"Size\", // Assuming 'Color' and 'Size', adjust keys if needed\n value: key,\n })),\n price: new decimal(variant.variantSellPrice || 0).mul(rate).toNumber().toFixed(2),\n vid: variant.vid,\n })),\n };\n}\n\nconst findProductById = async (productId: string) => {\n const result = await cjSdk.getProductDetails({\n pid: productId,\n });\n return result.data;\n};\n\nconst createOrUpdateProduct = async (\n product: Omit<Product, \"createdAt\" | \"id\" | \"updatedAt\">,\n payload: BasePayload,\n) => {\n const { totalDocs } = await payload.count({\n collection: \"products\",\n where: {\n pid: {\n equals: product.pid,\n },\n },\n });\n\n if (totalDocs === 0) {\n return payload.create({\n collection: \"products\",\n data: { ...product } as any,\n });\n }\n};\n\nexport const fetchExchangeRates = async () => {\n const response = await fetch(\"https://open.er-api.com/v6/latest/USD\");\n const data = await response.json();\n\n return data;\n};\n\nexport const syncProducts = async (productIds: string[], payload: BasePayload) => {\n const exchangeRates = await fetchExchangeRates();\n const storeSettings = await payload.findGlobal({\n slug: \"store-settings\",\n });\n const rate = exchangeRates.rates[storeSettings.currency || \"USD\"];\n\n const editorConfig = await editorConfigFactory.default({\n config: payload.config,\n });\n const products: ProductDetails[] = [];\n for (const productId of productIds) {\n const product = await findProductById(productId);\n if (!product) {\n continue;\n }\n products.push(product);\n await delay(1010);\n }\n const mappedProducts = products.map((product) => {\n return mapMockProductToSchema(product, editorConfig, rate, payload);\n });\n\n await Promise.all(\n mappedProducts.map((product) => createOrUpdateProduct(product as any, payload)),\n );\n\n return products;\n};\n"],"names":["convertHTMLToLexical","editorConfigFactory","decimal","JSDOM","cjSdk","path","dirname","fs","promisify","pipeline","writeFile","fileURLToPath","__filename","url","__dirname","streamPipeline","delay","ms","Promise","resolve","setTimeout","download","uri","filename","response","fetch","ok","Error","statusText","contentType","headers","get","contentLength","console","log","buffer","Buffer","from","arrayBuffer","error","uploadImageToPayload","src","payload","tempFilePath","join","uploadedImage","create","collection","data","alt","filePath","unlink","err","id","prefix","updatedAt","createdAt","thumbnailURL","mimeType","filesize","width","height","focalX","focalY","mapMockProductToSchema","product","editorConfig","rate","description","html","pid","title","productNameEn","variants","map","variant","imageUrl","variantImage","options","variantKey","split","key","index","option","value","price","variantSellPrice","mul","toNumber","toFixed","vid","findProductById","productId","result","getProductDetails","createOrUpdateProduct","totalDocs","count","where","equals","fetchExchangeRates","json","syncProducts","productIds","exchangeRates","storeSettings","findGlobal","slug","rates","currency","default","config","products","push","mappedProducts","all"],"mappings":"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"}
|
1
|
+
{"version":3,"sources":["../../src/service/sync-products.ts"],"sourcesContent":["import type { DefaultNodeTypes, TypedEditorState } from \"@payloadcms/richtext-lexical\";\nimport type { BasePayload } from \"payload\";\n\nimport { convertHTMLToLexical, editorConfigFactory } from \"@payloadcms/richtext-lexical\";\nimport decimal from \"decimal.js\";\nimport { JSDOM } from \"jsdom\";\n\nimport type { ProductDetails } from \"../sdk/products/product-types\";\n\nimport * as cjSdk from \"../sdk/cj-sdk\";\nimport path, { dirname, join } from \"path\";\nimport fs from \"fs\";\nimport { promisify } from \"util\";\nimport { pipeline } from \"stream\";\nimport { writeFile } from \"fs/promises\";\nimport { fileURLToPath } from \"url\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst streamPipeline = promisify(pipeline);\n\ninterface Product {\n description: TypedEditorState<DefaultNodeTypes>;\n pid: string;\n title: string;\n source: \"manual\" | \"cj\";\n variants?: Array<{\n imageUrl?: string;\n options?: Array<{ option: string; value: string }>;\n price?: number;\n vid: string;\n }>;\n}\n\nconst delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst download = async (uri: string, filename: string): Promise<void> => {\n try {\n const response = await fetch(uri);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch ${uri}: ${response.statusText}`);\n }\n\n const contentType = response.headers.get(\"content-type\");\n const contentLength = response.headers.get(\"content-length\");\n\n console.log(\"content-type:\", contentType);\n console.log(\"content-length:\", contentLength);\n\n const buffer = Buffer.from(await response.arrayBuffer());\n\n await writeFile(filename, buffer);\n\n console.log(\"Download complete:\", filename);\n } catch (error) {\n console.error(\"Error downloading file:\", error);\n }\n};\n\nasync function uploadImageToPayload(src: string, payload: BasePayload): Promise<any | null> {\n const tempFilePath = path.join(__dirname, \"temp-image.jpg\");\n\n try {\n // Fetch the image\n const response = await fetch(src);\n if (!response.ok) throw new Error(`Failed to fetch image: ${response.statusText}`);\n\n // Stream the response body to a temporary file\n await download(src, tempFilePath);\n\n // Upload the image using Payload's Local API\n const uploadedImage = await payload.create({\n collection: \"media\",\n data: {\n alt: \"Some alt text\",\n },\n\n filePath: tempFilePath,\n });\n\n console.log(\"Uploaded media document:\", uploadedImage);\n\n // Clean up: delete the temporary file\n fs.unlink(tempFilePath, (err) => {\n if (err) console.error(\"Error deleting temporary file:\", err);\n });\n\n return {\n id: uploadedImage.id,\n alt: uploadedImage.alt || \"\",\n prefix: \"media\",\n updatedAt: uploadedImage.updatedAt,\n createdAt: uploadedImage.createdAt,\n url: uploadedImage.url,\n thumbnailURL: uploadedImage.thumbnailURL || null,\n filename: uploadedImage.filename,\n mimeType: uploadedImage.mimeType,\n filesize: uploadedImage.filesize,\n width: uploadedImage.width,\n height: uploadedImage.height,\n focalX: 50,\n focalY: 50,\n };\n } catch (error) {\n console.error(\"Error uploading image:\", error);\n }\n}\nfunction mapMockProductToSchema(\n product: ProductDetails,\n editorConfig: any,\n rate: number,\n payload: BasePayload,\n) {\n return {\n description: convertHTMLToLexical({\n editorConfig,\n html: product.description || \"\",\n JSDOM,\n // uploadImage: async (src: string) => {\n // return uploadImageToPayload(src, payload);\n // },\n }),\n source: \"cj\",\n pid: product.pid,\n title: product.productNameEn,\n variants: product.variants?.map((variant) => ({\n imageUrl: variant.variantImage, // Map image URL to 'id' if using media collection\n options: variant.variantKey?.split(\"-\").map((key, index) => ({\n option: index === 0 ? \"Color\" : \"Size\", // Assuming 'Color' and 'Size', adjust keys if needed\n value: key,\n })),\n price: new decimal(variant.variantSellPrice || 0).mul(rate).toNumber().toFixed(2),\n vid: variant.vid,\n })),\n };\n}\n\nconst findProductById = async (productId: string) => {\n const result = await cjSdk.getProductDetails({\n pid: productId,\n });\n return result.data;\n};\n\nconst createOrUpdateProduct = async (\n product: Omit<Product, \"createdAt\" | \"id\" | \"updatedAt\">,\n payload: BasePayload,\n shopId?: string,\n) => {\n const { totalDocs } = await payload.count({\n collection: \"products\",\n where: {\n pid: {\n equals: product.pid,\n },\n },\n });\n\n if (totalDocs === 0) {\n return payload.create({\n collection: \"products\",\n data: {\n ...product,\n shop: shopId,\n } as any,\n });\n }\n};\n\nexport const fetchExchangeRates = async () => {\n const response = await fetch(\"https://open.er-api.com/v6/latest/USD\");\n const data = await response.json();\n\n return data;\n};\n\nexport const syncProducts = async (productIds: string[], payload: BasePayload, shopId?: string) => {\n const exchangeRates = await fetchExchangeRates();\n const storeSettings = await payload.findGlobal({\n slug: \"store-settings\",\n });\n const rate = exchangeRates.rates[storeSettings.currency || \"USD\"];\n\n const editorConfig = await editorConfigFactory.default({\n config: payload.config,\n });\n const products: ProductDetails[] = [];\n for (const productId of productIds) {\n const product = await findProductById(productId);\n if (!product) {\n continue;\n }\n products.push(product);\n await delay(1010);\n }\n const mappedProducts = products.map((product) => {\n return mapMockProductToSchema(product, editorConfig, rate, payload);\n });\n\n await Promise.all(\n mappedProducts.map((product) => createOrUpdateProduct(product as any, payload, shopId)),\n );\n\n return products;\n};\n"],"names":["convertHTMLToLexical","editorConfigFactory","decimal","JSDOM","cjSdk","path","dirname","fs","promisify","pipeline","writeFile","fileURLToPath","__filename","url","__dirname","streamPipeline","delay","ms","Promise","resolve","setTimeout","download","uri","filename","response","fetch","ok","Error","statusText","contentType","headers","get","contentLength","console","log","buffer","Buffer","from","arrayBuffer","error","uploadImageToPayload","src","payload","tempFilePath","join","uploadedImage","create","collection","data","alt","filePath","unlink","err","id","prefix","updatedAt","createdAt","thumbnailURL","mimeType","filesize","width","height","focalX","focalY","mapMockProductToSchema","product","editorConfig","rate","description","html","source","pid","title","productNameEn","variants","map","variant","imageUrl","variantImage","options","variantKey","split","key","index","option","value","price","variantSellPrice","mul","toNumber","toFixed","vid","findProductById","productId","result","getProductDetails","createOrUpdateProduct","shopId","totalDocs","count","where","equals","shop","fetchExchangeRates","json","syncProducts","productIds","exchangeRates","storeSettings","findGlobal","slug","rates","currency","default","config","products","push","mappedProducts","all"],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["export interface CJApiResponse<T> {\n code: number;\n result: boolean;\n message: string;\n data: T | null;\n requestId: string;\n}\n\nexport interface AccessTokenResponse {\n code: number;\n result: boolean;\n message: string;\n data: {\n accessToken: string;\n accessTokenExpiryDate: string | Date;\n refreshToken: string;\n refreshTokenExpiryDate: string | Date;\n createDate: string;\n } | null;\n requestId: string;\n}\n\nexport interface Variant {\n vid: string;\n pid: string;\n variantName: string | null;\n variantNameEn: string | null;\n variantSku: string;\n variantImage: string | null;\n variantStandard: string | null;\n variantUnit: string | null;\n variantProperty: string | null;\n variantKey: string;\n variantLength: number;\n variantWidth: number;\n variantHeight: number;\n variantVolume: number;\n variantWeight: number;\n variantSellPrice: number;\n variantSugSellPrice: number;\n createTime: string;\n}\n\nexport interface ProductDetailResponseData {\n pid: string;\n productName: string[];\n productNameEn: string;\n productSku: string;\n productImage: string;\n productWeight: number;\n productUnit: string;\n productType: string;\n categoryId: string;\n categoryName: string;\n entryCode: string;\n entryName: string;\n entryNameEn: string;\n materialName: string[];\n materialNameEn: string[];\n materialKey: string[];\n packingWeight: number;\n packingName: string[];\n packingNameEn: string[];\n packingKey: string[];\n productKey: string[];\n productKeyEn: string;\n sellPrice: number;\n sourceFrom: number;\n description: string;\n suggestSellPrice: string;\n listedNum: number;\n status: string;\n supplierName: string;\n supplierId: string;\n variants: Variant[];\n createrTime: string;\n}\n"],"names":[],"mappings":"AA2CA,WAiCC"}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import crypto from "crypto";
|
2
|
+
const getKey = (rawKey)=>{
|
3
|
+
return crypto.createHash("sha256").update(rawKey).digest();
|
4
|
+
};
|
5
|
+
const getTenantSecret = (tenantId)=>{
|
6
|
+
const key = tenantId;
|
7
|
+
if (!key) throw new Error(`Missing secret for tenant: ${tenantId}`);
|
8
|
+
return Buffer.from(key, "hex");
|
9
|
+
};
|
10
|
+
export const encryptToken = (token)=>{
|
11
|
+
const key = getKey(process.env.ENCRYPTION_KEY);
|
12
|
+
const iv = crypto.randomBytes(12);
|
13
|
+
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
|
14
|
+
const encrypted = Buffer.concat([
|
15
|
+
cipher.update(token, "utf8"),
|
16
|
+
cipher.final()
|
17
|
+
]);
|
18
|
+
const tag = cipher.getAuthTag();
|
19
|
+
const result = {
|
20
|
+
iv: iv.toString("hex"),
|
21
|
+
tag: tag.toString("hex"),
|
22
|
+
content: encrypted.toString("hex")
|
23
|
+
};
|
24
|
+
return Buffer.from(JSON.stringify(result)).toString("base64");
|
25
|
+
};
|
26
|
+
export const decryptToken = (encryptedToken)=>{
|
27
|
+
const key = getKey(process.env.ENCRYPTION_KEY);
|
28
|
+
const decoded = JSON.parse(Buffer.from(encryptedToken, "base64").toString("utf8"));
|
29
|
+
const iv = Buffer.from(decoded.iv, "hex");
|
30
|
+
const tag = Buffer.from(decoded.tag, "hex");
|
31
|
+
const content = Buffer.from(decoded.content, "hex");
|
32
|
+
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
|
33
|
+
decipher.setAuthTag(tag);
|
34
|
+
const decrypted = Buffer.concat([
|
35
|
+
decipher.update(content),
|
36
|
+
decipher.final()
|
37
|
+
]);
|
38
|
+
return decrypted.toString("utf8");
|
39
|
+
};
|
40
|
+
|
41
|
+
//# sourceMappingURL=manage-tokens.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../src/util/manage-tokens.ts"],"sourcesContent":["import crypto from \"crypto\";\n\ntype TokenPayload = string;\ntype EncryptedData = {\n iv: string;\n tag: string;\n content: string;\n};\n\nconst getKey = (rawKey: string): Buffer => {\n return crypto.createHash(\"sha256\").update(rawKey).digest();\n};\n\nconst getTenantSecret = (tenantId: string): Buffer => {\n const key = tenantId;\n if (!key) throw new Error(`Missing secret for tenant: ${tenantId}`);\n return Buffer.from(key, \"hex\");\n};\n\nexport const encryptToken = (token: TokenPayload): string => {\n const key = getKey(process.env.ENCRYPTION_KEY!);\n const iv = crypto.randomBytes(12);\n const cipher = crypto.createCipheriv(\"aes-256-gcm\", key, iv);\n\n const encrypted = Buffer.concat([cipher.update(token, \"utf8\"), cipher.final()]);\n\n const tag = cipher.getAuthTag();\n\n const result: EncryptedData = {\n iv: iv.toString(\"hex\"),\n tag: tag.toString(\"hex\"),\n content: encrypted.toString(\"hex\"),\n };\n\n return Buffer.from(JSON.stringify(result)).toString(\"base64\");\n};\n\nexport const decryptToken = (encryptedToken: string): string => {\n const key = getKey(process.env.ENCRYPTION_KEY!);\n const decoded = JSON.parse(\n Buffer.from(encryptedToken, \"base64\").toString(\"utf8\"),\n ) as EncryptedData;\n\n const iv = Buffer.from(decoded.iv, \"hex\");\n const tag = Buffer.from(decoded.tag, \"hex\");\n const content = Buffer.from(decoded.content, \"hex\");\n\n const decipher = crypto.createDecipheriv(\"aes-256-gcm\", key, iv);\n decipher.setAuthTag(tag);\n\n const decrypted = Buffer.concat([decipher.update(content), decipher.final()]);\n\n return decrypted.toString(\"utf8\");\n};\n"],"names":["crypto","getKey","rawKey","createHash","update","digest","getTenantSecret","tenantId","key","Error","Buffer","from","encryptToken","token","process","env","ENCRYPTION_KEY","iv","randomBytes","cipher","createCipheriv","encrypted","concat","final","tag","getAuthTag","result","toString","content","JSON","stringify","decryptToken","encryptedToken","decoded","parse","decipher","createDecipheriv","setAuthTag","decrypted"],"mappings":"AAAA,OAAOA,YAAY,SAAS;AAS5B,MAAMC,SAAS,CAACC;IACZ,OAAOF,OAAOG,UAAU,CAAC,UAAUC,MAAM,CAACF,QAAQG,MAAM;AAC5D;AAEA,MAAMC,kBAAkB,CAACC;IACrB,MAAMC,MAAMD;IACZ,IAAI,CAACC,KAAK,MAAM,IAAIC,MAAM,CAAC,2BAA2B,EAAEF,UAAU;IAClE,OAAOG,OAAOC,IAAI,CAACH,KAAK;AAC5B;AAEA,OAAO,MAAMI,eAAe,CAACC;IACzB,MAAML,MAAMP,OAAOa,QAAQC,GAAG,CAACC,cAAc;IAC7C,MAAMC,KAAKjB,OAAOkB,WAAW,CAAC;IAC9B,MAAMC,SAASnB,OAAOoB,cAAc,CAAC,eAAeZ,KAAKS;IAEzD,MAAMI,YAAYX,OAAOY,MAAM,CAAC;QAACH,OAAOf,MAAM,CAACS,OAAO;QAASM,OAAOI,KAAK;KAAG;IAE9E,MAAMC,MAAML,OAAOM,UAAU;IAE7B,MAAMC,SAAwB;QAC1BT,IAAIA,GAAGU,QAAQ,CAAC;QAChBH,KAAKA,IAAIG,QAAQ,CAAC;QAClBC,SAASP,UAAUM,QAAQ,CAAC;IAChC;IAEA,OAAOjB,OAAOC,IAAI,CAACkB,KAAKC,SAAS,CAACJ,SAASC,QAAQ,CAAC;AACxD,EAAE;AAEF,OAAO,MAAMI,eAAe,CAACC;IACzB,MAAMxB,MAAMP,OAAOa,QAAQC,GAAG,CAACC,cAAc;IAC7C,MAAMiB,UAAUJ,KAAKK,KAAK,CACtBxB,OAAOC,IAAI,CAACqB,gBAAgB,UAAUL,QAAQ,CAAC;IAGnD,MAAMV,KAAKP,OAAOC,IAAI,CAACsB,QAAQhB,EAAE,EAAE;IACnC,MAAMO,MAAMd,OAAOC,IAAI,CAACsB,QAAQT,GAAG,EAAE;IACrC,MAAMI,UAAUlB,OAAOC,IAAI,CAACsB,QAAQL,OAAO,EAAE;IAE7C,MAAMO,WAAWnC,OAAOoC,gBAAgB,CAAC,eAAe5B,KAAKS;IAC7DkB,SAASE,UAAU,CAACb;IAEpB,MAAMc,YAAY5B,OAAOY,MAAM,CAAC;QAACa,SAAS/B,MAAM,CAACwB;QAAUO,SAASZ,KAAK;KAAG;IAE5E,OAAOe,UAAUX,QAAQ,CAAC;AAC9B,EAAE"}
|