@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.
- package/dist/core/db/queries.d.ts +8 -8
- package/dist/core/db/schema.d.ts +4 -4
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/seo.d.ts +63 -0
- package/dist/core/seo.d.ts.map +1 -0
- package/dist/core/seo.js +107 -0
- package/dist/core/seo.js.map +1 -0
- package/package.json +1 -1
- package/dist/admin/components/AdminBarBanner.d.ts +0 -2
- package/dist/admin/components/AdminBarBanner.d.ts.map +0 -1
- package/dist/admin/components/AdminBarBanner.js +0 -266
- package/dist/admin/components/AdminBarBanner.js.map +0 -1
|
@@ -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
|
package/dist/core/db/schema.d.ts
CHANGED
|
@@ -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";
|
package/dist/core/index.d.ts
CHANGED
|
@@ -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
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -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"}
|
package/dist/core/index.js
CHANGED
|
@@ -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
|
package/dist/core/index.js.map
CHANGED
|
@@ -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"}
|
package/dist/core/seo.js
ADDED
|
@@ -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 +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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"}
|