@commercebuild/extension 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/tailwind.config.js +15 -0
- package/config/tsconfig.extension.json +23 -0
- package/config/vite.config.mjs +116 -0
- package/package.json +38 -0
- package/scripts/cli.js +30 -0
- package/scripts/utils.mjs +5 -0
- package/scripts/vite-plugin-hmr-notifier.mjs +44 -0
- package/types/category.d.ts +7 -0
- package/types/global.d.ts +71 -0
- package/types/index.d.ts +3 -0
- package/types/product.d.ts +14 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"moduleResolution": "node",
|
|
9
|
+
"allowImportingTsExtensions": true,
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"isolatedModules": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"jsx": "react-jsx",
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noUnusedLocals": false,
|
|
16
|
+
"noUnusedParameters": false,
|
|
17
|
+
"noFallthroughCasesInSwitch": true,
|
|
18
|
+
"declaration": true,
|
|
19
|
+
"declarationDir": "dist",
|
|
20
|
+
"outDir": "dist",
|
|
21
|
+
"types": ["commercebuild-extension"]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { defineConfig, loadEnv } from "vite";
|
|
2
|
+
import ViteHMRNotifierPlugin from "../scripts/vite-plugin-hmr-notifier.mjs";
|
|
3
|
+
import react from "@vitejs/plugin-react";
|
|
4
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
5
|
+
// import dts from "vite-plugin-dts";
|
|
6
|
+
// import { fileURLToPath } from "url";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import { existsSync } from "fs";
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
// const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
// const __dirname = dirname(__filename);
|
|
12
|
+
|
|
13
|
+
const jsEntry = path.resolve(process.cwd(), "src/index.js");
|
|
14
|
+
const tsEntry = path.resolve(process.cwd(), "src/index.ts");
|
|
15
|
+
const entryFile = existsSync(tsEntry) ? tsEntry : jsEntry;
|
|
16
|
+
|
|
17
|
+
const baseBuildConfig = {
|
|
18
|
+
lib: {
|
|
19
|
+
entry: entryFile,
|
|
20
|
+
name: "CBExtensionComponents",
|
|
21
|
+
formats: ["umd"],
|
|
22
|
+
fileName: (format, entryName) =>
|
|
23
|
+
`${entryName}.${format === "es" ? "mjs" : "js"}`,
|
|
24
|
+
},
|
|
25
|
+
minify: "esbuild",
|
|
26
|
+
sourcemap: false,
|
|
27
|
+
rollupOptions: {
|
|
28
|
+
output: {
|
|
29
|
+
assetFileNames: (assetInfo) => {
|
|
30
|
+
if (assetInfo.name.endsWith(".css")) {
|
|
31
|
+
return assetInfo.originalFileName || assetInfo.name || "asset.css";
|
|
32
|
+
}
|
|
33
|
+
return assetInfo.name;
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const prodConfig = {
|
|
40
|
+
plugins: [
|
|
41
|
+
react({
|
|
42
|
+
jsxRuntime: "automatic",
|
|
43
|
+
}),
|
|
44
|
+
tailwindcss(),
|
|
45
|
+
],
|
|
46
|
+
define: {
|
|
47
|
+
"process.env": {
|
|
48
|
+
NODE_ENV: JSON.stringify("production"),
|
|
49
|
+
NEXT_PUBLIC_IMAGE_DOMAINS: JSON.stringify(["*"]),
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
build: {
|
|
53
|
+
...baseBuildConfig,
|
|
54
|
+
minify: "esbuild",
|
|
55
|
+
sourcemap: false,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default defineConfig(({ mode, command }) => {
|
|
60
|
+
const env = loadEnv(mode, process.cwd(), "");
|
|
61
|
+
const devPort = env.PORT || 25521;
|
|
62
|
+
|
|
63
|
+
if (command === "serve") {
|
|
64
|
+
if (!env.COMMERCEBUILD_STORE_URL) {
|
|
65
|
+
throw new Error("Please setup COMMERCEBUILD_STORE_URL");
|
|
66
|
+
}
|
|
67
|
+
const serverUrl = `${env.COMMERCEBUILD_STORE_URL}${
|
|
68
|
+
env.COMMERCEBUILD_STORE_URL.includes("?") ? "&" : "?"
|
|
69
|
+
}devSource=http://localhost:${devPort}`;
|
|
70
|
+
|
|
71
|
+
console.log(
|
|
72
|
+
`\n ${chalk.green("commercebuild extension")} ${chalk.gray("ready")}:`
|
|
73
|
+
);
|
|
74
|
+
console.log(
|
|
75
|
+
`${chalk.green(" ➜ ")} ${chalk.white("Open Url:")} ${chalk.blue(serverUrl)}\n`
|
|
76
|
+
);
|
|
77
|
+
return {
|
|
78
|
+
root: ".",
|
|
79
|
+
plugins: [
|
|
80
|
+
ViteHMRNotifierPlugin(),
|
|
81
|
+
react({
|
|
82
|
+
jsxRuntime: "automatic",
|
|
83
|
+
}),
|
|
84
|
+
tailwindcss(),
|
|
85
|
+
],
|
|
86
|
+
define: {
|
|
87
|
+
"process.env": {
|
|
88
|
+
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
|
|
89
|
+
NEXT_PUBLIC_IMAGE_DOMAINS: JSON.stringify(["*"]),
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
server: {
|
|
93
|
+
port: devPort,
|
|
94
|
+
open: serverUrl,
|
|
95
|
+
cors: true,
|
|
96
|
+
headers: {
|
|
97
|
+
"Access-Control-Allow-Origin": "*",
|
|
98
|
+
"Access-Control-Allow-Methods":
|
|
99
|
+
"GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
100
|
+
"Access-Control-Allow-Headers":
|
|
101
|
+
"X-Requested-With, content-type, Authorization",
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
build: {
|
|
105
|
+
...baseBuildConfig,
|
|
106
|
+
},
|
|
107
|
+
// resolve: {
|
|
108
|
+
// alias: {
|
|
109
|
+
// "@": path.resolve(__dirname, "src"),
|
|
110
|
+
// },
|
|
111
|
+
// },
|
|
112
|
+
logLevel: "silent",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return prodConfig;
|
|
116
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@commercebuild/extension",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"types": "./types/index.d.ts",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./types/index.d.ts"
|
|
8
|
+
},
|
|
9
|
+
"./config/tailwind.config.js": "./config/tailwind.config.js",
|
|
10
|
+
"./config/tsconfig.extension.json": "./config/tsconfig.extension.json"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@commercebuild/ui": "^0.0.5",
|
|
14
|
+
"@commercebuild/platform-api": "^0.0.3",
|
|
15
|
+
"@headlessui/react": "^2.2.4",
|
|
16
|
+
"@tailwindcss/postcss": "^4.1.10",
|
|
17
|
+
"@tailwindcss/vite": "^4.1.11",
|
|
18
|
+
"@types/node": "^22.15.30",
|
|
19
|
+
"@types/react": "^19.1.8",
|
|
20
|
+
"@types/react-dom": "^19.1.6",
|
|
21
|
+
"@types/ws": "^8.18.1",
|
|
22
|
+
"@vitejs/plugin-react": "^4.5.2",
|
|
23
|
+
"chalk": "^5.4.1",
|
|
24
|
+
"esbuild": "^0.20.0",
|
|
25
|
+
"lucide-react": "^0.525.0",
|
|
26
|
+
"next": "^15.3.5",
|
|
27
|
+
"react": "^19.1.0",
|
|
28
|
+
"react-dom": "^19.1.0",
|
|
29
|
+
"tailwindcss": "^4.1.11",
|
|
30
|
+
"typescript": "^5.8.2",
|
|
31
|
+
"vite": "^7.0.4",
|
|
32
|
+
"vite-plugin-dts": "^4.5.4",
|
|
33
|
+
"ws": "^8.18.3"
|
|
34
|
+
},
|
|
35
|
+
"bin": {
|
|
36
|
+
"commercebuild-extension": "./scripts/cli.js"
|
|
37
|
+
}
|
|
38
|
+
}
|
package/scripts/cli.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from "child_process";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import { displayError } from "./utils.mjs";
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
|
|
11
|
+
if (args.includes("dev")) {
|
|
12
|
+
try {
|
|
13
|
+
const viteConfigPath = path.resolve(__dirname, "../config/vite.config.mjs");
|
|
14
|
+
execSync(`vite build --config ${viteConfigPath}`, { stdio: "inherit" });
|
|
15
|
+
execSync(`vite --config ${viteConfigPath}`, { stdio: "inherit" });
|
|
16
|
+
} catch (error) {
|
|
17
|
+
displayError("Failed to start commercebuild extension server:", error);
|
|
18
|
+
}
|
|
19
|
+
} else if (args.includes("build")) {
|
|
20
|
+
try {
|
|
21
|
+
const viteConfigPath = path.resolve(__dirname, "../config/vite.config.mjs");
|
|
22
|
+
execSync(`vite build --config ${viteConfigPath}`, { stdio: "inherit" });
|
|
23
|
+
} catch (error) {
|
|
24
|
+
displayError("Failed to build with commercebuild extension:", error);
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
displayError(
|
|
28
|
+
"No 'dev' or 'build' argument provided. Skipping commercebuild extension start."
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { build } from "vite";
|
|
2
|
+
import { WebSocketServer } from "ws";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
export default function ViteHMRNotifierPlugin() {
|
|
9
|
+
return {
|
|
10
|
+
name: "vite-hmr-notifier",
|
|
11
|
+
configureServer(server) {
|
|
12
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
13
|
+
server.httpServer.on("upgrade", (request, socket, head) => {
|
|
14
|
+
if (request.url === "/hmr-notifier") {
|
|
15
|
+
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
16
|
+
wss.emit("connection", ws, request);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
console.debug("[hmr-notifier] WebSocket mounted at /hmr-notifier");
|
|
21
|
+
let building = false;
|
|
22
|
+
server.watcher.on("change", async (file) => {
|
|
23
|
+
if (building) return;
|
|
24
|
+
building = true;
|
|
25
|
+
console.debug(`[hmr-notifier] File changed: ${file}, Rebuilding...`);
|
|
26
|
+
try {
|
|
27
|
+
await build({
|
|
28
|
+
configFile: path.resolve(__dirname, "../config/vite.config.mjs"),
|
|
29
|
+
logLevel: "silent",
|
|
30
|
+
});
|
|
31
|
+
console.debug(`[hmr-notifier] Build finished, notifying clients...`);
|
|
32
|
+
wss.clients.forEach((client) => {
|
|
33
|
+
if (client.readyState === 1) {
|
|
34
|
+
client.send(JSON.stringify({ type: "reload-remote-component" }));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error(`[hmr-notifier] Build failed:`, err);
|
|
39
|
+
}
|
|
40
|
+
building = false;
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import NextLink from "next/link";
|
|
2
|
+
import NextImage from "next/image";
|
|
3
|
+
import * as uis from "@commercebuild/ui";
|
|
4
|
+
import * as icons from "lucide-react";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import {
|
|
7
|
+
Disclosure,
|
|
8
|
+
DisclosureButton,
|
|
9
|
+
DisclosurePanel,
|
|
10
|
+
} from "@headlessui/react";
|
|
11
|
+
// import { Button } from "@commercebuild/ui";
|
|
12
|
+
// import * as categoryTypes from "./category";
|
|
13
|
+
|
|
14
|
+
declare global {
|
|
15
|
+
const cb: {
|
|
16
|
+
version: string;
|
|
17
|
+
React: typeof React;
|
|
18
|
+
utils: {
|
|
19
|
+
convertProductItemToCartRequestItem;
|
|
20
|
+
tlink;
|
|
21
|
+
tmsg;
|
|
22
|
+
router;
|
|
23
|
+
displayMoney;
|
|
24
|
+
cn;
|
|
25
|
+
};
|
|
26
|
+
com: {
|
|
27
|
+
Cart: {
|
|
28
|
+
AddToCart;
|
|
29
|
+
};
|
|
30
|
+
Category: {
|
|
31
|
+
CategoryProducts;
|
|
32
|
+
CategoryProduct;
|
|
33
|
+
CategoryBreadcrumb;
|
|
34
|
+
CategoryTitle;
|
|
35
|
+
CategorySidebar;
|
|
36
|
+
CategorySort;
|
|
37
|
+
CategoryProductsPageSize;
|
|
38
|
+
};
|
|
39
|
+
Product: {
|
|
40
|
+
ProductTitle;
|
|
41
|
+
ProductImages;
|
|
42
|
+
ProductPrice;
|
|
43
|
+
ProductStockStatus;
|
|
44
|
+
ProductStockQuantity;
|
|
45
|
+
ProductRating;
|
|
46
|
+
ProductDescription;
|
|
47
|
+
ProductTabs;
|
|
48
|
+
ProductQuantityInput;
|
|
49
|
+
StandardProductAddToCart;
|
|
50
|
+
VariantProductAddToCart;
|
|
51
|
+
ProductAddToFavorite;
|
|
52
|
+
ProductMakeOffer;
|
|
53
|
+
ProductRelatedProducts;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
ui: {
|
|
57
|
+
icons: { [K in keyof typeof icons]: (typeof icons)[K] };
|
|
58
|
+
Link: typeof NextLink;
|
|
59
|
+
Image: typeof NextImage;
|
|
60
|
+
Disclosure: typeof Disclosure;
|
|
61
|
+
DisclosureButton: typeof DisclosureButton;
|
|
62
|
+
DisclosurePanel: typeof DisclosurePanel;
|
|
63
|
+
} & { [K in keyof typeof uis]: (typeof uis)[K] };
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
interface Window {
|
|
67
|
+
cb: typeof cb;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export {};
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { catalog_v1 } from "@commercebuild/platform-api";
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
interface Product extends catalog_v1.CatalogProductSearchProduct {
|
|
5
|
+
image: Required<
|
|
6
|
+
Pick<catalog_v1.CatalogProductSearchProduct["details"]["images"], "main">
|
|
7
|
+
>["main"];
|
|
8
|
+
originalPrice?: catalog_v1.CatalogPriceItemDto;
|
|
9
|
+
formattedPrice: string;
|
|
10
|
+
href: string;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export {};
|