@rovela-ai/sdk 0.5.3 → 0.5.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.
@@ -634,16 +634,17 @@ export declare function getRecentOrders(limit?: number): Promise<{
634
634
  * Create a new order
635
635
  */
636
636
  export declare function createOrder(data: schema.NewOrder): Promise<{
637
- id: string;
638
637
  status: "pending" | "paid" | "shipped" | "delivered" | "cancelled" | "refunded" | "return_requested";
638
+ carrier: string | null;
639
+ email: string;
640
+ id: string;
641
+ total: string;
639
642
  createdAt: Date;
640
643
  updatedAt: Date;
641
644
  customerId: string | null;
642
- email: string;
643
645
  subtotal: string;
644
646
  tax: string;
645
647
  shipping: string;
646
- total: string;
647
648
  refundAmount: string | null;
648
649
  returnReason: string | null;
649
650
  discountCode: string | null;
@@ -676,7 +677,6 @@ export declare function createOrder(data: schema.NewOrder): Promise<{
676
677
  receiptUrl: string | null;
677
678
  trackingNumber: string | null;
678
679
  trackingUrl: string | null;
679
- carrier: string | null;
680
680
  labelUrl: string | null;
681
681
  shippoRateId: string | null;
682
682
  shippingMethod: string | null;
@@ -685,15 +685,15 @@ export declare function createOrder(data: schema.NewOrder): Promise<{
685
685
  * Create order items for an order
686
686
  */
687
687
  export declare function createOrderItems(items: schema.NewOrderItem[]): Promise<{
688
- id: string;
689
- name: string;
690
688
  price: string;
689
+ name: string;
690
+ id: string;
691
+ attributes: Record<string, string> | null;
692
+ quantity: number;
691
693
  createdAt: Date;
692
694
  productId: string;
693
- attributes: Record<string, string> | null;
694
695
  orderId: string;
695
696
  variantId: string | null;
696
- quantity: number;
697
697
  }[]>;
698
698
  /**
699
699
  * Update order status
@@ -2069,6 +2069,7 @@ export declare const storeSettings: import("drizzle-orm/pg-core").PgTableWithCol
2069
2069
  identity: undefined;
2070
2070
  generated: undefined;
2071
2071
  }, {}, {
2072
+ size: undefined;
2072
2073
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
2073
2074
  name: "shipping_countries";
2074
2075
  dataType: "string";
@@ -2077,7 +2078,6 @@ export declare const storeSettings: import("drizzle-orm/pg-core").PgTableWithCol
2077
2078
  enumValues: [string, ...string[]];
2078
2079
  driverParam: string;
2079
2080
  }, {}, {}, import("drizzle-orm").ColumnBuilderExtraConfig>;
2080
- size: undefined;
2081
2081
  }>;
2082
2082
  shippingMode: import("drizzle-orm/pg-core").PgColumn<{
2083
2083
  name: "shipping_mode";
@@ -2497,6 +2497,7 @@ export declare const shippingZones: import("drizzle-orm/pg-core").PgTableWithCol
2497
2497
  identity: undefined;
2498
2498
  generated: undefined;
2499
2499
  }, {}, {
2500
+ size: undefined;
2500
2501
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
2501
2502
  name: "countries";
2502
2503
  dataType: "string";
@@ -2505,7 +2506,6 @@ export declare const shippingZones: import("drizzle-orm/pg-core").PgTableWithCol
2505
2506
  enumValues: [string, ...string[]];
2506
2507
  driverParam: string;
2507
2508
  }, {}, {}, import("drizzle-orm").ColumnBuilderExtraConfig>;
2508
- size: undefined;
2509
2509
  }>;
2510
2510
  isActive: import("drizzle-orm/pg-core").PgColumn<{
2511
2511
  name: "is_active";
@@ -2858,6 +2858,7 @@ export declare const taxZones: import("drizzle-orm/pg-core").PgTableWithColumns<
2858
2858
  identity: undefined;
2859
2859
  generated: undefined;
2860
2860
  }, {}, {
2861
+ size: undefined;
2861
2862
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
2862
2863
  name: "countries";
2863
2864
  dataType: "string";
@@ -2866,7 +2867,6 @@ export declare const taxZones: import("drizzle-orm/pg-core").PgTableWithColumns<
2866
2867
  enumValues: [string, ...string[]];
2867
2868
  driverParam: string;
2868
2869
  }, {}, {}, import("drizzle-orm").ColumnBuilderExtraConfig>;
2869
- size: undefined;
2870
2870
  }>;
2871
2871
  states: import("drizzle-orm/pg-core").PgColumn<{
2872
2872
  name: "states";
@@ -2901,6 +2901,7 @@ export declare const taxZones: import("drizzle-orm/pg-core").PgTableWithColumns<
2901
2901
  identity: undefined;
2902
2902
  generated: undefined;
2903
2903
  }, {}, {
2904
+ size: undefined;
2904
2905
  baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
2905
2906
  name: "states";
2906
2907
  dataType: "string";
@@ -2909,7 +2910,6 @@ export declare const taxZones: import("drizzle-orm/pg-core").PgTableWithColumns<
2909
2910
  enumValues: [string, ...string[]];
2910
2911
  driverParam: string;
2911
2912
  }, {}, {}, import("drizzle-orm").ColumnBuilderExtraConfig>;
2912
- size: undefined;
2913
2913
  }>;
2914
2914
  taxRate: import("drizzle-orm/pg-core").PgColumn<{
2915
2915
  name: "tax_rate";
@@ -19,4 +19,6 @@ export { StoreSettingsProvider, useStoreSettings, useStoreSettingsOptional, } fr
19
19
  export type { StoreSettings, StoreSettingsContextValue, StoreSettingsProviderProps, } from './StoreSettingsProvider';
20
20
  export { cn, formatPrice, parsePrice, getCurrencySymbol, generateSlug, generateSKU, formatDate, formatRelativeTime, truncate, capitalize, titleCase, clamp, percentage, isValidEmail, isValidPhone, compact, pick, omit, sleep, retry, } from './utils';
21
21
  export type { FormatPriceOptions } from './utils';
22
+ export { serializeJsonLd, stripHtml, buildProductJsonLd, buildStoreJsonLdGraph, } from './seo';
23
+ export type { ProductSeoInput, StoreSeoContext, AggregateRatingInput, } from './seo';
22
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,cAAc,SAAS,CAAA;AAGvB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,yBAAyB,CAAA;AAEhC,YAAY,EACV,aAAa,EACb,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAEL,EAAE,EAEF,WAAW,EACX,UAAU,EACV,iBAAiB,EAEjB,YAAY,EAEZ,WAAW,EAEX,UAAU,EACV,kBAAkB,EAElB,QAAQ,EACR,UAAU,EACV,SAAS,EAET,KAAK,EACL,UAAU,EAEV,YAAY,EACZ,YAAY,EAEZ,OAAO,EACP,IAAI,EACJ,IAAI,EAEJ,KAAK,EACL,KAAK,GACN,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,cAAc,SAAS,CAAA;AAGvB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,yBAAyB,CAAA;AAEhC,YAAY,EACV,aAAa,EACb,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAEL,EAAE,EAEF,WAAW,EACX,UAAU,EACV,iBAAiB,EAEjB,YAAY,EAEZ,WAAW,EAEX,UAAU,EACV,kBAAkB,EAElB,QAAQ,EACR,UAAU,EACV,SAAS,EAET,KAAK,EACL,UAAU,EAEV,YAAY,EACZ,YAAY,EAEZ,OAAO,EACP,IAAI,EACJ,IAAI,EAEJ,KAAK,EACL,KAAK,GACN,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAGjD,OAAO,EACL,eAAe,EACf,SAAS,EACT,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,OAAO,CAAA;AACd,YAAY,EACV,eAAe,EACf,eAAe,EACf,oBAAoB,GACrB,MAAM,OAAO,CAAA"}
@@ -40,4 +40,6 @@ isValidEmail, isValidPhone,
40
40
  compact, pick, omit,
41
41
  // Async utilities
42
42
  sleep, retry, } from './utils';
43
+ // SEO / JSON-LD builders (pure, server-safe) — see ./seo
44
+ export { serializeJsonLd, stripHtml, buildProductJsonLd, buildStoreJsonLdGraph, } from './seo';
43
45
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,iDAAiD;AACjD,cAAc,SAAS,CAAA;AAEvB,kDAAkD;AAClD,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,yBAAyB,CAAA;AAQhC,qCAAqC;AACrC,OAAO;AACL,cAAc;AACd,EAAE;AACF,mBAAmB;AACnB,WAAW,EACX,UAAU,EACV,iBAAiB;AACjB,kBAAkB;AAClB,YAAY;AACZ,iBAAiB;AACjB,WAAW;AACX,kBAAkB;AAClB,UAAU,EACV,kBAAkB;AAClB,mBAAmB;AACnB,QAAQ,EACR,UAAU,EACV,SAAS;AACT,mBAAmB;AACnB,KAAK,EACL,UAAU;AACV,aAAa;AACb,YAAY,EACZ,YAAY;AACZ,mBAAmB;AACnB,OAAO,EACP,IAAI,EACJ,IAAI;AACJ,kBAAkB;AAClB,KAAK,EACL,KAAK,GACN,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,iDAAiD;AACjD,cAAc,SAAS,CAAA;AAEvB,kDAAkD;AAClD,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,yBAAyB,CAAA;AAQhC,qCAAqC;AACrC,OAAO;AACL,cAAc;AACd,EAAE;AACF,mBAAmB;AACnB,WAAW,EACX,UAAU,EACV,iBAAiB;AACjB,kBAAkB;AAClB,YAAY;AACZ,iBAAiB;AACjB,WAAW;AACX,kBAAkB;AAClB,UAAU,EACV,kBAAkB;AAClB,mBAAmB;AACnB,QAAQ,EACR,UAAU,EACV,SAAS;AACT,mBAAmB;AACnB,KAAK,EACL,UAAU;AACV,aAAa;AACb,YAAY,EACZ,YAAY;AACZ,mBAAmB;AACnB,OAAO,EACP,IAAI,EACJ,IAAI;AACJ,kBAAkB;AAClB,KAAK,EACL,KAAK,GACN,MAAM,SAAS,CAAA;AAIhB,yDAAyD;AACzD,OAAO,EACL,eAAe,EACf,SAAS,EACT,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,OAAO,CAAA"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Server-safe JSON-LD builders for storefront SEO + AI shopping discoverability.
3
+ *
4
+ * Pure functions, zero dependencies — safe to import from Server Components.
5
+ *
6
+ * Why this matters: JSON-LD MUST be server-rendered. GPTBot and OAI-SearchBot
7
+ * (the crawlers that decide ChatGPT Shopping / Perplexity / Google AI Mode
8
+ * citations) do NOT execute JavaScript, so client-injected structured data is
9
+ * invisible to them. Render the output of these builders with `serializeJsonLd`
10
+ * inside a server-rendered `<script type="application/ld+json">`.
11
+ */
12
+ export interface ProductSeoInput {
13
+ name: string;
14
+ slug: string;
15
+ description?: string | null;
16
+ /** Decimal string ("19.99") or number — coerced to a 2dp string for `Offer.price`. */
17
+ price: number | string;
18
+ images?: string[] | null;
19
+ sku?: string | null;
20
+ /** Caller computes from inventory / variants (see the PDP server shell). */
21
+ inStock: boolean;
22
+ }
23
+ export interface StoreSeoContext {
24
+ /** Absolute origin, e.g. `https://store.rovela.app`. May be empty during setup. */
25
+ storeUrl?: string | null;
26
+ storeName: string;
27
+ /** ISO 4217 currency code, e.g. "USD". */
28
+ currency: string;
29
+ }
30
+ export interface AggregateRatingInput {
31
+ ratingValue: number;
32
+ reviewCount: number;
33
+ }
34
+ /** Strip HTML tags + collapse whitespace. Defensive for stores that store rich-text descriptions. */
35
+ export declare function stripHtml(input: string): string;
36
+ /**
37
+ * Serialize JSON-LD with the `</` escape that prevents a `</script>` breakout
38
+ * (the same hardening the platform marketing site uses).
39
+ */
40
+ export declare function serializeJsonLd(data: Record<string, unknown>): string;
41
+ /**
42
+ * `Product` + `Offer` JSON-LD for a product detail page. This is THE signal AI
43
+ * shopping surfaces read first. `price`/`availability` must match the visible
44
+ * DOM (mismatches get the listing suppressed by Perplexity / Google).
45
+ *
46
+ * `aggregateRating` is supported but optional — the reviews table is opt-in
47
+ * (§27), so callers only pass it when reviews actually exist.
48
+ */
49
+ export declare function buildProductJsonLd(product: ProductSeoInput, ctx: StoreSeoContext & {
50
+ aggregateRating?: AggregateRatingInput | null;
51
+ }): Record<string, unknown>;
52
+ /**
53
+ * Site-wide `Organization` + `WebSite` JSON-LD graph for the storefront root
54
+ * layout. Establishes brand identity for AI assistants (reduces hallucination
55
+ * about the store).
56
+ */
57
+ export declare function buildStoreJsonLdGraph(ctx: {
58
+ storeUrl?: string | null;
59
+ storeName: string;
60
+ logoUrl?: string | null;
61
+ sameAs?: string[];
62
+ }): Record<string, unknown>;
63
+ //# sourceMappingURL=seo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../../src/core/seo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,sFAAsF;IACtF,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IACxB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,qGAAqG;AACrG,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAErE;AAWD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,eAAe,EACxB,GAAG,EAAE,eAAe,GAAG;IAAE,eAAe,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAA;CAAE,GACvE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsCzB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE;IACzC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwB1B"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Server-safe JSON-LD builders for storefront SEO + AI shopping discoverability.
3
+ *
4
+ * Pure functions, zero dependencies — safe to import from Server Components.
5
+ *
6
+ * Why this matters: JSON-LD MUST be server-rendered. GPTBot and OAI-SearchBot
7
+ * (the crawlers that decide ChatGPT Shopping / Perplexity / Google AI Mode
8
+ * citations) do NOT execute JavaScript, so client-injected structured data is
9
+ * invisible to them. Render the output of these builders with `serializeJsonLd`
10
+ * inside a server-rendered `<script type="application/ld+json">`.
11
+ */
12
+ /** Strip HTML tags + collapse whitespace. Defensive for stores that store rich-text descriptions. */
13
+ export function stripHtml(input) {
14
+ return input
15
+ .replace(/<[^>]*>/g, ' ')
16
+ .replace(/\s+/g, ' ')
17
+ .trim();
18
+ }
19
+ /**
20
+ * Serialize JSON-LD with the `</` escape that prevents a `</script>` breakout
21
+ * (the same hardening the platform marketing site uses).
22
+ */
23
+ export function serializeJsonLd(data) {
24
+ return JSON.stringify(data).replace(/</g, '\\u003c');
25
+ }
26
+ function toPriceString(price) {
27
+ const n = typeof price === 'string' ? Number(price) : price;
28
+ return Number.isFinite(n) ? n.toFixed(2) : String(price);
29
+ }
30
+ function trimTrailingSlash(url) {
31
+ return (url || '').replace(/\/$/, '');
32
+ }
33
+ /**
34
+ * `Product` + `Offer` JSON-LD for a product detail page. This is THE signal AI
35
+ * shopping surfaces read first. `price`/`availability` must match the visible
36
+ * DOM (mismatches get the listing suppressed by Perplexity / Google).
37
+ *
38
+ * `aggregateRating` is supported but optional — the reviews table is opt-in
39
+ * (§27), so callers only pass it when reviews actually exist.
40
+ */
41
+ export function buildProductJsonLd(product, ctx) {
42
+ const base = trimTrailingSlash(ctx.storeUrl);
43
+ const productUrl = base ? `${base}/products/${product.slug}` : undefined;
44
+ const description = product.description
45
+ ? stripHtml(product.description).slice(0, 5000)
46
+ : undefined;
47
+ const images = (product.images ?? []).filter(Boolean).slice(0, 8);
48
+ const offers = {
49
+ '@type': 'Offer',
50
+ price: toPriceString(product.price),
51
+ priceCurrency: ctx.currency,
52
+ availability: product.inStock
53
+ ? 'https://schema.org/InStock'
54
+ : 'https://schema.org/OutOfStock',
55
+ itemCondition: 'https://schema.org/NewCondition',
56
+ ...(productUrl && { url: productUrl }),
57
+ };
58
+ return {
59
+ '@context': 'https://schema.org',
60
+ '@type': 'Product',
61
+ ...(productUrl && { '@id': `${productUrl}#product` }),
62
+ name: product.name,
63
+ ...(description && { description }),
64
+ ...(images.length > 0 && { image: images }),
65
+ ...(product.sku && { sku: product.sku }),
66
+ brand: { '@type': 'Brand', name: ctx.storeName },
67
+ offers,
68
+ ...(ctx.aggregateRating &&
69
+ ctx.aggregateRating.reviewCount > 0 && {
70
+ aggregateRating: {
71
+ '@type': 'AggregateRating',
72
+ ratingValue: ctx.aggregateRating.ratingValue,
73
+ reviewCount: ctx.aggregateRating.reviewCount,
74
+ },
75
+ }),
76
+ };
77
+ }
78
+ /**
79
+ * Site-wide `Organization` + `WebSite` JSON-LD graph for the storefront root
80
+ * layout. Establishes brand identity for AI assistants (reduces hallucination
81
+ * about the store).
82
+ */
83
+ export function buildStoreJsonLdGraph(ctx) {
84
+ const base = trimTrailingSlash(ctx.storeUrl);
85
+ const orgId = base ? `${base}/#organization` : undefined;
86
+ return {
87
+ '@context': 'https://schema.org',
88
+ '@graph': [
89
+ {
90
+ '@type': 'Organization',
91
+ ...(orgId && { '@id': orgId }),
92
+ name: ctx.storeName,
93
+ ...(base && { url: base }),
94
+ ...(ctx.logoUrl && { logo: ctx.logoUrl }),
95
+ ...(ctx.sameAs && ctx.sameAs.length > 0 && { sameAs: ctx.sameAs }),
96
+ },
97
+ {
98
+ '@type': 'WebSite',
99
+ ...(base && { '@id': `${base}/#website` }),
100
+ name: ctx.storeName,
101
+ ...(base && { url: base }),
102
+ ...(orgId && { publisher: { '@id': orgId } }),
103
+ },
104
+ ],
105
+ };
106
+ }
107
+ //# sourceMappingURL=seo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo.js","sourceRoot":"","sources":["../../src/core/seo.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rovela-ai/sdk",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "Rovela SDK - Pre-built e-commerce components for AI-powered store generation",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,2 +0,0 @@
1
- export declare function AdminBarBanner(): import("react").ReactPortal | null;
2
- //# sourceMappingURL=AdminBarBanner.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AdminBarBanner.d.ts","sourceRoot":"","sources":["../../../src/admin/components/AdminBarBanner.tsx"],"names":[],"mappings":"AAoDA,wBAAgB,cAAc,uCA4I7B"}
@@ -1,266 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- /**
4
- * @rovela/sdk/admin/components/AdminBarBanner
5
- *
6
- * Linear/Vercel-style admin session bar shown above the storefront whenever
7
- * a signed-in admin browses the public store. Customers and anonymous
8
- * visitors never see it.
9
- *
10
- * Design rules (unchanged from v1):
11
- *
12
- * 1. Self-gating. No props. Renders `null` while loading, for sessions
13
- * without a role, and on /admin/*.
14
- *
15
- * 2. Portal-rendered to <html>. Combined with a `translateZ(0)` on
16
- * <body> and a 40px body margin, fixed/sticky store chrome is pushed
17
- * below the bar instead of overlapping it.
18
- *
19
- * 3. Theme-proof. Inline styles + one scoped <style> element.
20
- *
21
- * 4. Navigation-only. Server-side guards still authorize.
22
- *
23
- * v2 changes:
24
- * - Two actions instead of one: "Edit store" (rovela.ai/generate/{id})
25
- * and "Manage store" (/admin). Both open in a new tab.
26
- * - "Edit store" only renders when NEXT_PUBLIC_ROVELA_PROJECT_ID is set.
27
- * This gives a graceful degradation path for stores whose env var
28
- * hasn't propagated yet.
29
- * - Rovela logo (same CDN asset as AdminNav sidebar footer) as the
30
- * Edit-store glyph; Lucide LayoutDashboard as the Manage-store glyph.
31
- */
32
- import { useEffect, useState } from 'react';
33
- import { createPortal } from 'react-dom';
34
- import { usePathname } from 'next/navigation';
35
- import { LayoutDashboard } from 'lucide-react';
36
- import { useAdminAuth } from '../hooks/useAdminAuth';
37
- // =============================================================================
38
- // Constants
39
- // =============================================================================
40
- const BAR_HEIGHT_PX = 40;
41
- const PORTAL_ROOT_ID = 'rovela-admin-bar-root';
42
- const STYLE_TAG_ID = 'rovela-admin-bar-style';
43
- const DEFAULT_ROVELA_URL = 'https://rovela.ai';
44
- const ROVELA_LOGO_SRC = 'https://rovela.ai/logo.png';
45
- // =============================================================================
46
- // Component
47
- // =============================================================================
48
- export function AdminBarBanner() {
49
- const pathname = usePathname();
50
- const { admin, isAuthenticated, isLoading } = useAdminAuth();
51
- const [portalRoot, setPortalRoot] = useState(null);
52
- const visible = !isLoading &&
53
- isAuthenticated &&
54
- Boolean(admin?.role) &&
55
- !pathname?.startsWith('/admin');
56
- useEffect(() => {
57
- if (typeof document === 'undefined')
58
- return;
59
- if (!visible)
60
- return;
61
- // --- Portal root (<html> child, sibling of <body>) ---
62
- let root = document.getElementById(PORTAL_ROOT_ID);
63
- let ownsRoot = false;
64
- if (!root) {
65
- root = document.createElement('div');
66
- root.id = PORTAL_ROOT_ID;
67
- document.documentElement.appendChild(root);
68
- ownsRoot = true;
69
- }
70
- // Pattern B — post-mount hydration of a DOM portal root (browser-only).
71
- // Alternative is useSyncExternalStore against a document.documentElement subscription.
72
- // eslint-disable-next-line react-hooks/set-state-in-effect
73
- setPortalRoot(root);
74
- // --- Scoped global stylesheet (pseudo-states + responsive hides) ---
75
- let styleEl = document.getElementById(STYLE_TAG_ID);
76
- let ownsStyle = false;
77
- if (!styleEl) {
78
- styleEl = document.createElement('style');
79
- styleEl.id = STYLE_TAG_ID;
80
- styleEl.textContent = GLOBAL_CSS;
81
- document.head.appendChild(styleEl);
82
- ownsStyle = true;
83
- }
84
- // --- Push the storefront down + reparent fixed descendants ---
85
- const prevBodyMarginTop = document.body.style.marginTop;
86
- const prevBodyTransform = document.body.style.transform;
87
- document.body.style.marginTop = `${BAR_HEIGHT_PX}px`;
88
- document.body.style.transform = 'translateZ(0)';
89
- return () => {
90
- document.body.style.marginTop = prevBodyMarginTop;
91
- document.body.style.transform = prevBodyTransform;
92
- if (ownsStyle && styleEl?.parentNode) {
93
- styleEl.parentNode.removeChild(styleEl);
94
- }
95
- if (ownsRoot && root?.parentNode) {
96
- root.parentNode.removeChild(root);
97
- }
98
- setPortalRoot(null);
99
- };
100
- }, [visible]);
101
- if (!visible || !portalRoot || !admin)
102
- return null;
103
- // Deep-link to Rovela platform. Only shown when the project ID env var is
104
- // present — which is the case for every store that has redeployed since
105
- // the env var was added to buildStoreEnvVars(). Older stores see only the
106
- // "Manage store" button until their next rebuild.
107
- const projectId = getEnv('NEXT_PUBLIC_ROVELA_PROJECT_ID');
108
- const rovelaBase = getEnv('NEXT_PUBLIC_ROVELA_URL') || DEFAULT_ROVELA_URL;
109
- const editUrl = projectId ? `${rovelaBase.replace(/\/$/, '')}/generate/${projectId}` : null;
110
- // Store name surfaces in the left group so a merchant managing multiple
111
- // stores instantly knows which storefront they're viewing. Falls back to
112
- // hiding the name (just "Live store") when the env var isn't set.
113
- const storeName = (getEnv('STORE_NAME') || '').trim() || null;
114
- return createPortal(_jsx("div", { "data-rovela-admin-bar": "", role: "region", "aria-label": "Admin view \u2014 only you see this bar", style: wrapStyle, children: _jsxs("div", { style: innerStyle, children: [_jsxs("div", { style: leftGroupStyle, children: [_jsx("span", { "aria-hidden": "true", style: dotStyle }), _jsx("span", { "data-rovela-desktop-only": "", style: disclosureStyle, children: "Admin view \u2014 only you see this bar" }), storeName && (_jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": "true", "data-rovela-desktop-only": "", style: dividerStyle, children: "\u00B7" }), _jsx("span", { "data-rovela-tablet-only": "", style: storeNameStyle, children: storeName })] }))] }), _jsxs("div", { style: actionsStyle, children: [editUrl && (_jsxs("a", { href: editUrl, target: "_blank", rel: "noopener noreferrer", "data-rovela-action": "", "aria-label": "Edit store in Rovela", style: buttonStyle, children: [_jsx("img", { src: ROVELA_LOGO_SRC, alt: "", "aria-hidden": "true", style: rovelaIconStyle }), _jsx("span", { "data-rovela-desktop-only": "", children: "Edit store" })] })), _jsxs("a", { href: "/admin", target: "_blank", rel: "noopener noreferrer", "data-rovela-action": "", "aria-label": "Open the admin dashboard", style: buttonStyle, children: [_jsx(LayoutDashboard, { "aria-hidden": "true", style: lucideIconStyle, strokeWidth: 1.8 }), _jsx("span", { "data-rovela-desktop-only": "", children: "Manage store" })] })] })] }) }), portalRoot);
115
- }
116
- // =============================================================================
117
- // Helpers
118
- // =============================================================================
119
- /**
120
- * `NEXT_PUBLIC_*` vars get statically inlined by Next.js when a component
121
- * is bundled, so reading via `process.env[name]` with a dynamic key does
122
- * not work in the SDK (no direct access to the compile-time substitution).
123
- * We read the literal strings so the bundler can substitute them.
124
- */
125
- function getEnv(key) {
126
- if (key === 'NEXT_PUBLIC_ROVELA_PROJECT_ID')
127
- return process.env.NEXT_PUBLIC_ROVELA_PROJECT_ID;
128
- if (key === 'NEXT_PUBLIC_ROVELA_URL')
129
- return process.env.NEXT_PUBLIC_ROVELA_URL;
130
- if (key === 'STORE_NAME')
131
- return process.env.STORE_NAME;
132
- return undefined;
133
- }
134
- // =============================================================================
135
- // Styles
136
- // =============================================================================
137
- const wrapStyle = {
138
- position: 'fixed',
139
- top: 0,
140
- left: 0,
141
- right: 0,
142
- height: `${BAR_HEIGHT_PX}px`,
143
- zIndex: 2147483647,
144
- background: 'rgba(10, 10, 12, 0.85)',
145
- backdropFilter: 'blur(12px) saturate(140%)',
146
- WebkitBackdropFilter: 'blur(12px) saturate(140%)',
147
- borderBottom: '1px solid rgba(255, 255, 255, 0.06)',
148
- color: '#FFFFFF',
149
- fontFamily: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
150
- fontSize: '13px',
151
- lineHeight: 1.3,
152
- letterSpacing: '-0.005em',
153
- boxSizing: 'border-box',
154
- };
155
- const innerStyle = {
156
- maxWidth: '1280px',
157
- height: '100%',
158
- margin: '0 auto',
159
- padding: '0 16px',
160
- display: 'flex',
161
- alignItems: 'center',
162
- justifyContent: 'space-between',
163
- gap: '12px',
164
- boxSizing: 'border-box',
165
- };
166
- const leftGroupStyle = {
167
- display: 'inline-flex',
168
- alignItems: 'center',
169
- gap: '8px',
170
- minWidth: 0,
171
- overflow: 'hidden',
172
- };
173
- const dotStyle = {
174
- width: '6px',
175
- height: '6px',
176
- borderRadius: '9999px',
177
- background: '#22C55E',
178
- boxShadow: '0 0 0 0 rgba(34, 197, 94, 0.6)',
179
- animation: 'rab-pulse 2.4s infinite',
180
- flexShrink: 0,
181
- };
182
- const disclosureStyle = {
183
- color: 'rgba(255, 255, 255, 0.7)',
184
- fontWeight: 400,
185
- whiteSpace: 'nowrap',
186
- };
187
- const dividerStyle = {
188
- color: 'rgba(255, 255, 255, 0.3)',
189
- };
190
- const storeNameStyle = {
191
- color: 'rgba(255, 255, 255, 0.75)',
192
- fontWeight: 500,
193
- whiteSpace: 'nowrap',
194
- overflow: 'hidden',
195
- textOverflow: 'ellipsis',
196
- minWidth: 0,
197
- };
198
- const actionsStyle = {
199
- display: 'inline-flex',
200
- alignItems: 'center',
201
- gap: '6px',
202
- flexShrink: 0,
203
- };
204
- const buttonStyle = {
205
- display: 'inline-flex',
206
- alignItems: 'center',
207
- gap: '6px',
208
- height: '28px',
209
- padding: '0 10px',
210
- borderRadius: '6px',
211
- fontSize: '12.5px',
212
- fontWeight: 500,
213
- color: '#FFFFFF',
214
- background: 'rgba(255, 255, 255, 0.1)',
215
- border: '1px solid rgba(255, 255, 255, 0.12)',
216
- textDecoration: 'none',
217
- cursor: 'pointer',
218
- whiteSpace: 'nowrap',
219
- flexShrink: 0,
220
- transition: 'background 120ms ease, border-color 120ms ease',
221
- };
222
- const rovelaIconStyle = {
223
- width: '14px',
224
- height: '14px',
225
- objectFit: 'contain',
226
- // Force the logo to render pure white so it reads correctly on the dark bar
227
- filter: 'brightness(0) invert(1)',
228
- flexShrink: 0,
229
- };
230
- const lucideIconStyle = {
231
- width: '14px',
232
- height: '14px',
233
- flexShrink: 0,
234
- };
235
- // Scoped under [data-rovela-admin-bar] so no rules can escape into the
236
- // storefront. Injected on mount, removed on unmount.
237
- //
238
- // Responsive hide rules:
239
- // - [data-rovela-desktop-only] hidden below 640px (role tag, button labels)
240
- // - [data-rovela-tablet-only] hidden below 480px ("Admin session" label)
241
- const GLOBAL_CSS = `
242
- @keyframes rab-pulse {
243
- 0% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.55); }
244
- 70% { box-shadow: 0 0 0 6px rgba(34, 197, 94, 0); }
245
- 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
246
- }
247
- [data-rovela-admin-bar] a[data-rovela-action]:hover {
248
- background: rgba(255, 255, 255, 0.18) !important;
249
- border-color: rgba(255, 255, 255, 0.2) !important;
250
- }
251
- [data-rovela-admin-bar] a[data-rovela-action]:focus-visible {
252
- outline: 2px solid rgba(255, 255, 255, 0.6);
253
- outline-offset: 2px;
254
- }
255
- @media (max-width: 639px) {
256
- [data-rovela-admin-bar] [data-rovela-desktop-only] { display: none !important; }
257
- }
258
- @media (max-width: 479px) {
259
- [data-rovela-admin-bar] [data-rovela-tablet-only] { display: none !important; }
260
- [data-rovela-admin-bar] a[data-rovela-action] { padding: 0 8px; }
261
- }
262
- @media (prefers-reduced-motion: reduce) {
263
- [data-rovela-admin-bar] [aria-hidden="true"] { animation: none !important; }
264
- }
265
- `;
266
- //# sourceMappingURL=AdminBarBanner.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AdminBarBanner.js","sourceRoot":"","sources":["../../../src/admin/components/AdminBarBanner.tsx"],"names":[],"mappings":"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"}