bsign-customization-full 0.0.1 → 0.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bsign-customization-full",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -1,5 +1,6 @@
1
1
  import { type JSX, type ReactNode } from "react";
2
2
  import { ScrollArea } from "./ui/scroll-area";
3
+ import { resolveAssetUrl } from "../lib/asset-url";
3
4
 
4
5
  export default function ConstructureSidebar({ items, onSelectItem, children, selectedItem }: {
5
6
  items: Array<{
@@ -13,7 +14,7 @@ export default function ConstructureSidebar({ items, onSelectItem, children, sel
13
14
  return (
14
15
  <div className="flex h-full w-full flex-col border-b border-[#D6D6D6] md:flex-row md:border-r md:border-b-0">
15
16
  <div className="flex w-full items-center gap-3 overflow-x-auto border-b border-[#D6D6D6] bg-[#F4F4F4] p-3 md:h-full md:w-[110px] md:flex-col md:items-center md:gap-4 md:overflow-visible md:border-b-0 md:py-[15px] md:rounded-tl-3xl 2xl:w-[200px]">
16
- <img src="/logo.png" className="h-[30px] w-[74px] shrink-0 md:h-[37px] md:w-[92px]" />
17
+ <img src={resolveAssetUrl("/logo.png")} className="h-[30px] w-[74px] shrink-0 md:h-[37px] md:w-[92px]" />
17
18
  {items.map(item => {
18
19
  const Icon = item.icon;
19
20
  return (
@@ -7,9 +7,10 @@ import { Textarea } from "../ui/textarea"
7
7
  import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, ImageIcon, TypeIcon } from "lucide-react"
8
8
  import { ToggleGroup, ToggleGroupItem } from "../ui/toggle-group"
9
9
  import { useState } from "react"
10
- import { Checkbox } from "../ui/checkbox"
11
- import { Input } from "../ui/input"
10
+ import { Checkbox } from "../ui/checkbox"
11
+ import { Input } from "../ui/input"
12
12
  import { getMaxLineLengthByPt } from "../../lib/config-font"
13
+ import { resolveAssetUrl } from "../../lib/asset-url"
13
14
 
14
15
  export default function LayersContainer() {
15
16
  const { layers, init: setLayers, options } = useLayersStore()
@@ -94,11 +95,11 @@ export default function LayersContainer() {
94
95
  {layer.type === "image" && isImageLayer(layer) && (
95
96
  <div className="flex flex-col gap-4">
96
97
  <div className="flex items-center justify-center p-4 bg-slate-50 rounded-lg border-2 border-dashed border-slate-200">
97
- <img
98
- src={layer.props.imageSrc || "/placeholder.svg"}
99
- className={`h-16 max-w-full object-contain rounded shadow-sm`}
100
- alt="Layer preview"
101
- />
98
+ <img
99
+ src={layer.props.imageSrc || resolveAssetUrl("/placeholder.svg")}
100
+ className={`h-16 max-w-full object-contain rounded shadow-sm`}
101
+ alt="Layer preview"
102
+ />
102
103
  </div>
103
104
  </div>
104
105
  )}
@@ -3,9 +3,10 @@ import {
3
3
  DialogPortal,
4
4
  DialogOverlay,
5
5
  } from "./ui/dialog"
6
- import * as DialogPrimitive from "@radix-ui/react-dialog"
7
- import { cn } from "../lib/utils"
8
- import { X } from "lucide-react"
6
+ import * as DialogPrimitive from "@radix-ui/react-dialog"
7
+ import { cn } from "../lib/utils"
8
+ import { X } from "lucide-react"
9
+ import { resolveAssetUrl } from "../lib/asset-url"
9
10
 
10
11
  interface ImportFileModalProps {
11
12
  open: boolean
@@ -39,7 +40,7 @@ export function SizeGuideModal({
39
40
  Close
40
41
  </DialogPrimitive.Close>
41
42
  </div>
42
- <img src="/size-guide.webp" className="w-full h-auto rounded-2xl object-contain" />
43
+ <img src={resolveAssetUrl("/size-guide.webp")} className="w-full h-auto rounded-2xl object-contain" />
43
44
  </DialogPrimitive.Content>
44
45
  </DialogPortal>
45
46
  </Dialog>
@@ -0,0 +1,70 @@
1
+ const ABSOLUTE_URL_PATTERN = /^(?:[a-z][a-z\d+\-.]*:)?\/\//i
2
+ const SPECIAL_PROTOCOL_PATTERN = /^(?:data|blob):/i
3
+
4
+ function toBaseUrl(url: string): string | undefined {
5
+ try {
6
+ return new URL(".", url).toString()
7
+ } catch {
8
+ return undefined
9
+ }
10
+ }
11
+
12
+ function resolveDefaultAssetBaseUrl(): string {
13
+ const importMetaBase = toBaseUrl(import.meta.url)
14
+ if (importMetaBase) {
15
+ return importMetaBase
16
+ }
17
+
18
+ if (typeof document !== "undefined") {
19
+ const currentScript = document.currentScript
20
+ if (currentScript instanceof HTMLScriptElement && currentScript.src) {
21
+ const scriptBase = toBaseUrl(currentScript.src)
22
+ if (scriptBase) {
23
+ return scriptBase
24
+ }
25
+ }
26
+
27
+ const scripts = document.getElementsByTagName("script")
28
+ const lastScript = scripts.item(scripts.length - 1)
29
+ if (lastScript instanceof HTMLScriptElement && lastScript.src) {
30
+ const scriptBase = toBaseUrl(lastScript.src)
31
+ if (scriptBase) {
32
+ return scriptBase
33
+ }
34
+ }
35
+ }
36
+
37
+ if (typeof window !== "undefined") {
38
+ return toBaseUrl(window.location.href) ?? "/"
39
+ }
40
+
41
+ return "/"
42
+ }
43
+
44
+ let assetBaseUrl = resolveDefaultAssetBaseUrl()
45
+
46
+ export function setAssetBaseUrl(baseUrl?: string) {
47
+ if (!baseUrl) {
48
+ assetBaseUrl = resolveDefaultAssetBaseUrl()
49
+ return
50
+ }
51
+
52
+ assetBaseUrl = toBaseUrl(baseUrl) ?? assetBaseUrl
53
+ }
54
+
55
+ export function getAssetBaseUrl() {
56
+ return assetBaseUrl
57
+ }
58
+
59
+ export function resolveAssetUrl(path: string): string {
60
+ if (!path) {
61
+ return path
62
+ }
63
+
64
+ if (ABSOLUTE_URL_PATTERN.test(path) || SPECIAL_PROTOCOL_PATTERN.test(path)) {
65
+ return path
66
+ }
67
+
68
+ const normalizedPath = path.startsWith("/") ? path.slice(1) : path
69
+ return new URL(normalizedPath, getAssetBaseUrl()).toString()
70
+ }
package/src/lib/config.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { LayrProps, TLayer } from "../components/preview";
2
2
  import { BASE_FONT_SIZE } from "./config-font";
3
+ import { resolveAssetUrl } from "./asset-url";
3
4
 
4
5
  export const prodApiUrl = "https://constructor-api-production.up.railway.app/v1/product/generate";
5
6
 
@@ -85,12 +86,12 @@ export const getSizeLimitScale = (size: Pick<TSize, "cm">): number => {
85
86
 
86
87
  const MODERN_BACKGROUND_ASSETS = {
87
88
  rectangle: {
88
- black: "/templates/assets/modern/rectangle-black.webp",
89
- white: "/templates/assets/modern/rectangle-white.webp",
89
+ black: resolveAssetUrl("/templates/assets/modern/rectangle-black.webp"),
90
+ white: resolveAssetUrl("/templates/assets/modern/rectangle-white.webp"),
90
91
  },
91
92
  square: {
92
- black: "/templates/assets/modern/square-black.webp",
93
- white: "/templates/assets/modern/square-white.webp",
93
+ black: resolveAssetUrl("/templates/assets/modern/square-black.webp"),
94
+ white: resolveAssetUrl("/templates/assets/modern/square-white.webp"),
94
95
  },
95
96
  } as const;
96
97
 
@@ -199,38 +200,38 @@ const WAVE_MATERIALS = [
199
200
  {
200
201
  id: "anthracite-gray",
201
202
  label: "Anthracite Gray",
202
- previewImage: "/colors/anthracite-gray_50x50.png",
203
- image: "/colors/anthracite-gray.webp",
203
+ previewImage: resolveAssetUrl("/colors/anthracite-gray_50x50.png"),
204
+ image: resolveAssetUrl("/colors/anthracite-gray.webp"),
204
205
  },
205
206
  {
206
207
  id: "indian-rosewood",
207
208
  label: "Indian Rosewood",
208
- previewImage: "/colors/indian-rosewood_50x50.png",
209
- image: "/colors/indian-rosewood.webp",
209
+ previewImage: resolveAssetUrl("/colors/indian-rosewood_50x50.png"),
210
+ image: resolveAssetUrl("/colors/indian-rosewood.webp"),
210
211
  },
211
212
  {
212
213
  id: "natural-wood",
213
214
  label: "Natural Wood",
214
- previewImage: "/colors/natural-wood_50x50.png",
215
- image: "/colors/natural-wood.webp",
215
+ previewImage: resolveAssetUrl("/colors/natural-wood_50x50.png"),
216
+ image: resolveAssetUrl("/colors/natural-wood.webp"),
216
217
  },
217
218
  {
218
219
  id: "walnut",
219
220
  label: "Walnut",
220
- previewImage: "/colors/walnut_50x50.png",
221
- image: "/colors/walnut.webp",
221
+ previewImage: resolveAssetUrl("/colors/walnut_50x50.png"),
222
+ image: resolveAssetUrl("/colors/walnut.webp"),
222
223
  },
223
224
  {
224
225
  id: "redwood",
225
226
  label: "Redwood",
226
- previewImage: "/colors/redwood_50x50.png",
227
- image: "/colors/redwood.webp",
227
+ previewImage: resolveAssetUrl("/colors/redwood_50x50.png"),
228
+ image: resolveAssetUrl("/colors/redwood.webp"),
228
229
  },
229
230
  {
230
231
  id: "dark-wenge",
231
232
  label: "Dark Wenge",
232
- previewImage: "/colors/dark-wenge_50x50.png",
233
- image: "/colors/dark-wenge.webp",
233
+ previewImage: resolveAssetUrl("/colors/dark-wenge_50x50.png"),
234
+ image: resolveAssetUrl("/colors/dark-wenge.webp"),
234
235
  },
235
236
  ] as const;
236
237
 
@@ -400,7 +401,7 @@ const modernTemplate: TemplateDefinition = {
400
401
  const waveTemplate: TemplateDefinition = {
401
402
  id: "wave",
402
403
  name: "Wave",
403
- image: "/templates/wave.webp",
404
+ image: resolveAssetUrl("/templates/wave.webp"),
404
405
  textFont: "font-bebasneue",
405
406
  defaultShapeId: "square",
406
407
  defaultMaterialId: "anthracite-gray",
@@ -410,7 +411,7 @@ const waveTemplate: TemplateDefinition = {
410
411
  id: "square",
411
412
  label: "Square",
412
413
  sizes: SQUARE_SIZES,
413
- previewImage: "/templates/wave.webp",
414
+ previewImage: resolveAssetUrl("/templates/wave.webp"),
414
415
  },
415
416
  ],
416
417
  materials: WAVE_MATERIALS.map((material) => ({
@@ -440,7 +441,7 @@ const waveTemplate: TemplateDefinition = {
440
441
  {
441
442
  type: "image",
442
443
  props: {
443
- imageSrc: "/templates/assets/wave.webp",
444
+ imageSrc: resolveAssetUrl("/templates/assets/wave.webp"),
444
445
  coordinates: {
445
446
  "3.5x3.5": { x: -35, y: 90 },
446
447
  "5x5": { x: -35, y: 100 },