wiki-plugin-shoppe 0.0.43 → 0.0.45
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
package/server/server.js
CHANGED
|
@@ -84,10 +84,24 @@ function getSanoraUrl() {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
function getAddieUrl() {
|
|
87
|
-
|
|
87
|
+
const sanora = getSanoraUrl();
|
|
88
|
+
try {
|
|
89
|
+
const url = new URL(sanora);
|
|
90
|
+
// Only derive from origin when sanora is a wiki proxy URL (has a path component).
|
|
91
|
+
// A bare host:port URL (e.g. http://localhost:7243) means Addie is on its own port.
|
|
92
|
+
if (url.pathname && url.pathname !== '/') {
|
|
93
|
+
return url.origin + '/plugin/allyabase/addie';
|
|
94
|
+
}
|
|
95
|
+
} catch { /* fall through */ }
|
|
88
96
|
return `http://localhost:${process.env.ADDIE_PORT || 3005}`;
|
|
89
97
|
}
|
|
90
98
|
|
|
99
|
+
// Returns the public-facing Sanora URL (via wiki proxy) for browser-visible resource URLs.
|
|
100
|
+
// Always constructed from the current request so it matches the host the browser is using.
|
|
101
|
+
function getSanoraPublicUrl(req) {
|
|
102
|
+
return `${reqProto(req)}://${req.get('host')}/plugin/allyabase/sanora`;
|
|
103
|
+
}
|
|
104
|
+
|
|
91
105
|
function getLucilleUrl() {
|
|
92
106
|
const config = loadConfig();
|
|
93
107
|
if (config.lucilleUrl) return config.lucilleUrl.replace(/\/$/, '');
|
|
@@ -1501,7 +1515,7 @@ async function processArchive(zipPath, onProgress = () => {}) {
|
|
|
1501
1515
|
// PORTFOLIO PAGE GENERATION
|
|
1502
1516
|
// ============================================================
|
|
1503
1517
|
|
|
1504
|
-
async function getShoppeGoods(tenant) {
|
|
1518
|
+
async function getShoppeGoods(tenant, imageBaseUrl) {
|
|
1505
1519
|
let products = {};
|
|
1506
1520
|
try {
|
|
1507
1521
|
const resp = await fetch(`${getSanoraUrl()}/products/${tenant.uuid}`, { timeout: 15000 });
|
|
@@ -1556,7 +1570,7 @@ async function getShoppeGoods(tenant) {
|
|
|
1556
1570
|
description: product.description || '',
|
|
1557
1571
|
price: product.price || 0,
|
|
1558
1572
|
shipping: product.shipping || 0,
|
|
1559
|
-
image: product.image ? `${getSanoraUrl()}/images/${product.image}` : null,
|
|
1573
|
+
image: product.image ? `${imageBaseUrl || getSanoraUrl()}/images/${product.image}` : null,
|
|
1560
1574
|
url: resolvedUrl,
|
|
1561
1575
|
...(isPost && { category: product.category, tags: product.tags || '' }),
|
|
1562
1576
|
...(lucillePlayerUrl && { lucillePlayerUrl }),
|
|
@@ -3207,7 +3221,7 @@ async function startServer(params) {
|
|
|
3207
3221
|
const product = products[title] || Object.values(products).find(p => p.title === title);
|
|
3208
3222
|
if (!product) return res.status(404).send('<h1>Product not found</h1>');
|
|
3209
3223
|
|
|
3210
|
-
const imageUrl = product.image ? `${
|
|
3224
|
+
const imageUrl = product.image ? `${sanoraUrl}/images/${product.image}` : '';
|
|
3211
3225
|
const ebookUrl = `${wikiOrigin}/plugin/shoppe/${tenant.uuid}/download/${encodeURIComponent(title)}`;
|
|
3212
3226
|
const shoppeUrl = `${wikiOrigin}/plugin/shoppe/${tenant.uuid}`;
|
|
3213
3227
|
const payees = tenant.addieKeys
|
|
@@ -3278,7 +3292,7 @@ async function startServer(params) {
|
|
|
3278
3292
|
const schedule = await getAppointmentSchedule(tenant, product);
|
|
3279
3293
|
const wikiOrigin = `${reqProto(req)}://${req.get('host')}`;
|
|
3280
3294
|
const shoppeUrl = `${wikiOrigin}/plugin/shoppe/${tenant.uuid}`;
|
|
3281
|
-
const imageUrl = product.image ? `${
|
|
3295
|
+
const imageUrl = product.image ? `${getSanoraPublicUrl(req)}/images/${product.image}` : '';
|
|
3282
3296
|
|
|
3283
3297
|
const price = product.price || 0;
|
|
3284
3298
|
const html = fillTemplate(APPOINTMENT_BOOKING_TMPL, {
|
|
@@ -3346,7 +3360,7 @@ async function startServer(params) {
|
|
|
3346
3360
|
const tierInfo = await getTierInfo(tenant, product);
|
|
3347
3361
|
const wikiOrigin = `${reqProto(req)}://${req.get('host')}`;
|
|
3348
3362
|
const shoppeUrl = `${wikiOrigin}/plugin/shoppe/${tenant.uuid}`;
|
|
3349
|
-
const imageUrl = product.image ? `${
|
|
3363
|
+
const imageUrl = product.image ? `${getSanoraPublicUrl(req)}/images/${product.image}` : '';
|
|
3350
3364
|
const benefits = tierInfo && tierInfo.benefits
|
|
3351
3365
|
? tierInfo.benefits.map(b => `<li>${escHtml(b)}</li>`).join('')
|
|
3352
3366
|
: '';
|
|
@@ -3527,7 +3541,7 @@ async function startServer(params) {
|
|
|
3527
3541
|
productId: product.productId,
|
|
3528
3542
|
description: product.description || '',
|
|
3529
3543
|
price: product.price || 0,
|
|
3530
|
-
image: product.image ? `${
|
|
3544
|
+
image: product.image ? `${getSanoraPublicUrl(req)}/images/${product.image}` : null,
|
|
3531
3545
|
benefits: tierInfo ? (tierInfo.benefits || []) : [],
|
|
3532
3546
|
renewalDays: tierInfo ? (tierInfo.renewalDays || 30) : 30,
|
|
3533
3547
|
active: status.active,
|
|
@@ -4036,14 +4050,15 @@ async function startServer(params) {
|
|
|
4036
4050
|
if (!purchased) return res.status(403).send('<h1>No purchase found for this key</h1>');
|
|
4037
4051
|
}
|
|
4038
4052
|
|
|
4039
|
-
const
|
|
4053
|
+
const sanoraPublicUrl = getSanoraPublicUrl(req);
|
|
4054
|
+
const imageUrl = product.image ? `${sanoraPublicUrl}/images/${product.image}` : '';
|
|
4040
4055
|
|
|
4041
4056
|
// Map artifact UUIDs to download paths by extension
|
|
4042
4057
|
let epubPath = '', pdfPath = '', mobiPath = '';
|
|
4043
4058
|
(product.artifacts || []).forEach(artifact => {
|
|
4044
|
-
if (artifact.includes('epub')) epubPath = `${
|
|
4045
|
-
if (artifact.includes('pdf')) pdfPath = `${
|
|
4046
|
-
if (artifact.includes('mobi')) mobiPath = `${
|
|
4059
|
+
if (artifact.includes('epub')) epubPath = `${sanoraPublicUrl}/artifacts/${artifact}`;
|
|
4060
|
+
if (artifact.includes('pdf')) pdfPath = `${sanoraPublicUrl}/artifacts/${artifact}`;
|
|
4061
|
+
if (artifact.includes('mobi')) mobiPath = `${sanoraPublicUrl}/artifacts/${artifact}`;
|
|
4047
4062
|
});
|
|
4048
4063
|
|
|
4049
4064
|
const html = fillTemplate(EBOOK_DOWNLOAD_TMPL, {
|
|
@@ -4089,7 +4104,7 @@ async function startServer(params) {
|
|
|
4089
4104
|
const fm = parseFrontMatter(mdContent);
|
|
4090
4105
|
const postTitle = fm.title || title;
|
|
4091
4106
|
const postDate = fm.date || '';
|
|
4092
|
-
const imageUrl = product.image ? `${
|
|
4107
|
+
const imageUrl = product.image ? `${getSanoraPublicUrl(req)}/images/${product.image}` : null;
|
|
4093
4108
|
|
|
4094
4109
|
res.set('Content-Type', 'text/html');
|
|
4095
4110
|
res.send(generatePostHTML(tenant, postTitle, postDate, imageUrl, fm.body || mdContent));
|
|
@@ -4164,7 +4179,7 @@ async function startServer(params) {
|
|
|
4164
4179
|
productId: product.productId,
|
|
4165
4180
|
title: product.title,
|
|
4166
4181
|
category: product.category,
|
|
4167
|
-
image: product.image ? `${
|
|
4182
|
+
image: product.image ? `${getSanoraPublicUrl(req)}/images/${product.image}` : null,
|
|
4168
4183
|
price: product.price,
|
|
4169
4184
|
paidAt: match.paidAt,
|
|
4170
4185
|
status: match.status,
|
|
@@ -4190,7 +4205,7 @@ async function startServer(params) {
|
|
|
4190
4205
|
try {
|
|
4191
4206
|
const tenant = getTenantByIdentifier(req.params.identifier);
|
|
4192
4207
|
if (!tenant) return res.status(404).json({ error: 'Shoppe not found' });
|
|
4193
|
-
const goods = await getShoppeGoods(tenant);
|
|
4208
|
+
const goods = await getShoppeGoods(tenant, getSanoraPublicUrl(req));
|
|
4194
4209
|
const cat = req.query.category;
|
|
4195
4210
|
res.json({ success: true, goods: (cat && goods[cat]) ? goods[cat] : goods });
|
|
4196
4211
|
} catch (err) {
|
|
@@ -4212,7 +4227,7 @@ async function startServer(params) {
|
|
|
4212
4227
|
const tracks = [];
|
|
4213
4228
|
for (const [key, product] of Object.entries(products)) {
|
|
4214
4229
|
if (product.category !== 'music') continue;
|
|
4215
|
-
const cover = product.image ? `${
|
|
4230
|
+
const cover = product.image ? `${getSanoraPublicUrl(req)}/images/${product.image}` : null;
|
|
4216
4231
|
const artifacts = product.artifacts || [];
|
|
4217
4232
|
if (artifacts.length > 1) {
|
|
4218
4233
|
albums.push({
|
|
@@ -4246,7 +4261,7 @@ async function startServer(params) {
|
|
|
4246
4261
|
try {
|
|
4247
4262
|
const tenant = getTenantByIdentifier(req.params.identifier);
|
|
4248
4263
|
if (!tenant) return res.status(404).send('<h1>Shoppe not found</h1>');
|
|
4249
|
-
const goods = await getShoppeGoods(tenant);
|
|
4264
|
+
const goods = await getShoppeGoods(tenant, getSanoraPublicUrl(req));
|
|
4250
4265
|
|
|
4251
4266
|
// Check if the request carries a valid owner signature — if so, embed auth
|
|
4252
4267
|
// params in the page so the upload button can authenticate with upload-info.
|
|
@@ -193,7 +193,7 @@
|
|
|
193
193
|
return p;
|
|
194
194
|
}).filter(p => p.pubKey);
|
|
195
195
|
}
|
|
196
|
-
|
|
196
|
+
var URL_PAYEES = parseUrlPayees();
|
|
197
197
|
</script>
|
|
198
198
|
|
|
199
199
|
<!-- ── Shoppere (pubKey) path ────────────────────────────────────────────── -->
|
|
@@ -202,7 +202,7 @@
|
|
|
202
202
|
const _buyerPubKey = '{{buyerPubKey}}' || new URLSearchParams(window.location.search).get('pubKey') || '';
|
|
203
203
|
const _buyerTimestamp = '{{buyerTimestamp}}' || new URLSearchParams(window.location.search).get('timestamp') || '';
|
|
204
204
|
const _buyerSignature = '{{buyerSignature}}' || new URLSearchParams(window.location.search).get('signature') || '';
|
|
205
|
-
|
|
205
|
+
var IS_SHOPPERE = !!(_buyerPubKey && _buyerTimestamp && _buyerSignature);
|
|
206
206
|
// Affiliate (NFC proximity charge / referral link) param — present when buyer arrived via a referred link
|
|
207
207
|
const _affiliatePubKey = new URLSearchParams(window.location.search).get('affiliatePubKey') || '';
|
|
208
208
|
const IS_AFFILIATE_CHARGE = !!_affiliatePubKey;
|