@redeemid/emdash 0.0.24 → 0.0.25
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/README.md +44 -636
- package/docs/access.md +131 -0
- package/docs/content.md +84 -0
- package/docs/developer-api.md +24 -4
- package/docs/getting-started.md +94 -0
- package/docs/production.md +52 -0
- package/docs/reference.md +128 -0
- package/docs/shop.md +65 -0
- package/docs/shopify-flow.md +1 -1
- package/docs/shopify-setup.md +4 -4
- package/docs/staff.md +81 -0
- package/package.json +2 -1
- package/src/api-version.ts +1 -1
- package/src/components/Content.astro +7 -1
- package/src/components/Gate.astro +3 -0
- package/src/components/MemberCard.astro +3 -0
- package/src/components/Plan.astro +3 -0
- package/src/components/Preferences.astro +3 -0
- package/src/components/YourData.astro +3 -0
- package/src/contract.ts +1 -0
- package/src/guard.ts +23 -2
- package/src/plugin.ts +19 -2
- package/src/route-cache.ts +134 -0
- package/src/settings.ts +9 -0
- package/src/template-scan.ts +33 -6
- package/src/version.ts +1 -1
package/src/template-scan.ts
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
* every rule, Paywall break and Members only part, so a gated collection
|
|
5
5
|
* rendered that way reaches every visitor in full.
|
|
6
6
|
*
|
|
7
|
+
* Also templates that call `Astro.cache.set()` themselves on a gated
|
|
8
|
+
* collection's pages instead of cacheEntry()/cachePage() (route-cache.ts):
|
|
9
|
+
* the route cache then serves one reader's copy to everyone.
|
|
10
|
+
*
|
|
7
11
|
* redeemidGuard() scans the site's src/ at build time (scanTemplate, in
|
|
8
12
|
* Node) and hands the findings to the running site; the Status page then
|
|
9
13
|
* compares them with the rules as they are now (gatedFindings), because
|
|
@@ -17,8 +21,10 @@ import type { RedeemIDConfig } from "./config.js";
|
|
|
17
21
|
export interface TemplateFinding {
|
|
18
22
|
/** Path from the site's root, e.g. src/pages/[slug].astro. */
|
|
19
23
|
file: string;
|
|
20
|
-
/** Lines with a <PortableText> tag. */
|
|
24
|
+
/** Lines with a <PortableText> tag (from emdash/ui). */
|
|
21
25
|
lines: number[];
|
|
26
|
+
/** Lines that call Astro.cache.set() directly; absent when there are none. */
|
|
27
|
+
cache?: number[];
|
|
22
28
|
/** Collections the file loads with getEmDashEntry or getEmDashCollection. */
|
|
23
29
|
collections: string[];
|
|
24
30
|
}
|
|
@@ -26,16 +32,20 @@ export interface TemplateFinding {
|
|
|
26
32
|
const FROM_EMDASH_UI = /import\s*\{[^}]*\bPortableText\b[^}]*\}\s*from\s*["']emdash\/ui["']/;
|
|
27
33
|
const LOADS = /getEmDash(?:Entry|Collection)\(\s*["'`]([\w-]+)["'`]/g;
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
const CACHE_SET = /\bAstro\.cache\??\.set\(/;
|
|
36
|
+
|
|
37
|
+
/** One template's finding, or null when it neither renders <PortableText> from emdash/ui nor sets a cache hint. */
|
|
30
38
|
export function scanTemplate(file: string, source: string): TemplateFinding | null {
|
|
31
|
-
|
|
39
|
+
const fromUi = FROM_EMDASH_UI.test(source);
|
|
32
40
|
const lines: number[] = [];
|
|
41
|
+
const cache: number[] = [];
|
|
33
42
|
source.split("\n").forEach((line, i) => {
|
|
34
|
-
if (/<PortableText[\s/>]/.test(line)) lines.push(i + 1);
|
|
43
|
+
if (fromUi && /<PortableText[\s/>]/.test(line)) lines.push(i + 1);
|
|
44
|
+
if (CACHE_SET.test(line)) cache.push(i + 1);
|
|
35
45
|
});
|
|
36
|
-
if (!lines.length) return null;
|
|
46
|
+
if (!lines.length && !cache.length) return null;
|
|
37
47
|
const collections = [...new Set([...source.matchAll(LOADS)].map((m) => m[1]!))].sort();
|
|
38
|
-
return { file, lines, collections };
|
|
48
|
+
return cache.length ? { file, lines, cache, collections } : { file, lines, collections };
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
/** Collections some rule or entry rule can lock: "*" when the site default does. */
|
|
@@ -61,12 +71,29 @@ export function gatedFindings(findings: TemplateFinding[], config: RedeemIDConfi
|
|
|
61
71
|
if (!gated.size) return [];
|
|
62
72
|
const all = gated.has("*");
|
|
63
73
|
return findings.flatMap((f) => {
|
|
74
|
+
if (!f.lines.length) return [];
|
|
64
75
|
if (!f.collections.length) return [{ ...f, gated: [] }];
|
|
65
76
|
const hit = f.collections.filter((c) => all || gated.has(c));
|
|
66
77
|
return hit.length ? [{ ...f, gated: hit }] : [];
|
|
67
78
|
});
|
|
68
79
|
}
|
|
69
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Templates that set a route cache hint themselves on pages that load a
|
|
83
|
+
* gated collection. Files whose collection we can't see (layouts, which set
|
|
84
|
+
* hints for menus and settings) aren't listed: cacheEntry() on the page keeps
|
|
85
|
+
* those out anyway.
|
|
86
|
+
*/
|
|
87
|
+
export function cacheFindings(findings: TemplateFinding[], config: RedeemIDConfig): GatedFinding[] {
|
|
88
|
+
const gated = gatedCollections(config);
|
|
89
|
+
if (!gated.size) return [];
|
|
90
|
+
const all = gated.has("*");
|
|
91
|
+
return findings.flatMap((f) => {
|
|
92
|
+
const hit = f.collections.filter((c) => all || gated.has(c));
|
|
93
|
+
return f.cache?.length && hit.length ? [{ ...f, gated: hit }] : [];
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
70
97
|
/** Where the running site keeps the scan; unset when redeemidGuard() isn't installed. */
|
|
71
98
|
export const TEMPLATES_KEY = "__redeemidTemplates";
|
|
72
99
|
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.0.
|
|
1
|
+
export const VERSION = "0.0.25";
|