@sparkletree/cli 0.6.0 → 0.7.0

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 CHANGED
@@ -22,12 +22,18 @@ sparkletree list
22
22
  sparkletree help
23
23
  ```
24
24
 
25
- `upgrade` ports hero/cta copies made by a 0.3.0 `add` to the 0.4.0 reservation
26
- wiring (the hold now reserves space with your fallback instead of rendering
27
- nothing; see LAYOUT-DOCTRINE.md in the repo). It rewrites a copy only where
28
- it still matches the 0.3.0 template exactly, ignoring the Tailwind classes you
29
- were invited to change; a copy edited where the wiring lands is left untouched
30
- and reported, never guessed at. `--dry-run` previews the verdicts.
25
+ `upgrade` ports hero/cta copies from any earlier `add` to the current template
26
+ wiring, one generation at a time: a 0.3.0 copy gets the 0.4.0 reservation
27
+ wiring (the hold reserves space with your fallback instead of rendering
28
+ nothing; see LAYOUT-DOCTRINE.md in the repo) and then the 0.6.1 change that
29
+ imports `safeActionUrl` from `@sparkletree/core` instead of freezing a local
30
+ copy; a 0.4.0/0.5.0 copy gets only the latter. What a copy is missing is
31
+ decided by its content, never by guessing a version. It rewrites a copy only
32
+ where it still matches the template it came from exactly, ignoring the
33
+ Tailwind classes you were invited to change; a copy edited where the wiring
34
+ lands is left untouched and reported, never guessed at. `--dry-run` previews
35
+ the verdicts, and nothing is written when the installed packages are older
36
+ than the rewritten copy needs to compile.
31
37
 
32
38
  | Option | What it does |
33
39
  |---|---|
package/dist/bin.js CHANGED
@@ -16,7 +16,7 @@ const HELP = `sparkletree — add SparkleTree components to your project
16
16
 
17
17
  Usage
18
18
  sparkletree add <component...> [options]
19
- sparkletree upgrade [options] port 0.3.0 copies to the 0.4.0 reservation wiring
19
+ sparkletree upgrade [options] port copied components to the current template wiring
20
20
  sparkletree list
21
21
  sparkletree help
22
22
 
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The files `add` ACTUALLY wrote at v0.5.0, extracted from the tagged
3
+ * registry byte for byte (the same doctrine as the 0.3.0 fixtures in
4
+ * upgrade.test.ts: only the real output can falsify the codemod's `find`
5
+ * claims). Machine-generated from `git show v0.5.0:cli/src/registry.ts` —
6
+ * do not "tidy" these.
7
+ */
8
+ export declare const HERO_050 = "\"use client\";\n\nimport { StreamText, useIsland, withReserve, type UseIslandOptions } from \"@sparkletree/react\";\nimport type { FieldState } from \"@sparkletree/react\";\nimport { themeStyle } from \"@sparkletree/core\";\n\n/**\n * Your hero. Edit freely \u2014 this file is yours.\n *\n * What you should NOT need to touch, and what you will not find here: when the\n * copy paints, how long it holds, whether it types or lands composed, and\n * whether it carries the adaptation mark. All of that lives in\n * @sparkletree/core and @sparkletree/react so it can be fixed for you without\n * you re-copying this file.\n *\n * `fallback` is required. There is no loading state and no skeleton: if the\n * network is slow or the campaign is unreachable, this copy is what your\n * visitor reads. Write it as if it were the only version \u2014 often it is.\n *\n * Requires Tailwind CSS for the default classes \u2014 swap them freely.\n */\nexport interface HeroProps {\n campaignId: string;\n /** First paint. Real copy, never a placeholder. */\n fallback: UseIslandOptions[\"fallback\"];\n}\n\n/**\n * Server-driven URLs are configuration, not trust. Only http(s), mailto and\n * tel absolutes and relative navigations (\"/\", \"./\", \"#\", \"?\") pass; anything\n * else \u2014 javascript:, data:, an unprefixed string \u2014 is dropped.\n */\nfunction safeActionUrl(url: string | null | undefined): string | undefined {\n if (!url) return undefined;\n if (\n (url.startsWith(\"/\") && !url.startsWith(\"//\")) ||\n url.startsWith(\"./\") ||\n url.startsWith(\"#\") ||\n url.startsWith(\"?\")\n ) {\n return url;\n }\n try {\n const protocol = new URL(url).protocol;\n if ([\"https:\", \"http:\", \"mailto:\", \"tel:\"].includes(protocol)) return url;\n } catch {\n // Not a parseable URL at all.\n }\n return undefined;\n}\n\nexport function Hero({ campaignId, fallback }: HeroProps) {\n const { state, ref } = useIsland({ campaignId, island: \"hero\", fallback });\n const backgroundImage = safeActionUrl(state.backgroundImage);\n\n // The hold RESERVES (LAYOUT-DOCTRINE.md): while the canvas waits, each\n // field carries its fallback so StreamText keeps the geometry invisibly \u2014\n // nothing below the hero moves whichever way the wait ends. Delete this\n // and the section collapses during the hold; it is load-bearing.\n const holding = state.phase === \"holding\";\n const reserveOf = (name: \"greeting\" | \"headline\" | \"body\") =>\n state.held?.[name] || fallback[name];\n const held = (field: FieldState, reserve?: string) =>\n holding && reserve && !field.text ? withReserve(field, reserve) : field;\n\n return (\n <section\n ref={ref}\n className=\"relative overflow-hidden rounded-2xl p-10\"\n style={themeStyle(state.theme)}\n >\n {backgroundImage ? (\n <img\n src={backgroundImage}\n alt=\"\"\n className=\"absolute inset-0 h-full w-full object-cover\"\n />\n ) : null}\n\n <div className=\"relative\">\n {state.fields.greeting.text || (holding && reserveOf(\"greeting\")) ? (\n <StreamText\n field={held(state.fields.greeting, reserveOf(\"greeting\"))}\n as=\"p\"\n className=\"text-sm uppercase tracking-wide opacity-80\"\n />\n ) : null}\n\n {/* h2 to match the packaged Hero. The heading level is yours: pass\n as=\"h1\" if this section is your page's primary heading. */}\n <StreamText\n field={held(state.fields.headline, reserveOf(\"headline\"))}\n as=\"h2\"\n className=\"mt-2 text-4xl font-semibold\"\n />\n\n {state.fields.body.text || (holding && reserveOf(\"body\")) ? (\n <StreamText\n field={held(state.fields.body, reserveOf(\"body\"))}\n as=\"p\"\n className=\"mt-4 max-w-prose\"\n />\n ) : null}\n </div>\n </section>\n );\n}\n";
9
+ export declare const CTA_050 = "\"use client\";\n\nimport { StreamText, useIsland, useSparkletree, withReserve, type UseIslandOptions } from \"@sparkletree/react\";\nimport { readableTextColor, themeStyle, track } from \"@sparkletree/core\";\n\n/**\n * Your call to action. Edit freely.\n *\n * The button keeps its size while the label streams in, so the surrounding\n * layout does not shift under the visitor's cursor mid-click.\n *\n * Requires Tailwind CSS for the default classes \u2014 swap them freely.\n */\nexport interface CtaProps extends Omit<UseIslandOptions, \"island\"> {\n /** Where the button goes when the server has not resolved an action. */\n href?: string;\n onClick?: () => void;\n}\n\n/**\n * Server-driven URLs are configuration, not trust. Only http(s), mailto and\n * tel absolutes and relative navigations (\"/\", \"./\", \"#\", \"?\") pass; anything\n * else \u2014 javascript:, data:, an unprefixed string \u2014 is dropped.\n */\nfunction safeActionUrl(url: string | null | undefined): string | undefined {\n if (!url) return undefined;\n if (\n (url.startsWith(\"/\") && !url.startsWith(\"//\")) ||\n url.startsWith(\"./\") ||\n url.startsWith(\"#\") ||\n url.startsWith(\"?\")\n ) {\n return url;\n }\n try {\n const protocol = new URL(url).protocol;\n if ([\"https:\", \"http:\", \"mailto:\", \"tel:\"].includes(protocol)) return url;\n } catch {\n // Not a parseable URL at all.\n }\n return undefined;\n}\n\nexport function Cta(props: CtaProps) {\n const { href, onClick, ...islandOptions } = props;\n const { apiBase, organizationId } = useSparkletree();\n const { state, ref } = useIsland({ ...islandOptions, island: \"cta\" });\n // A rejected server action falls back to the href prop you control. The\n // prop is vetted too \u2014 the same render path, the same rules, one outcome.\n const action = safeActionUrl(state.ctaAction) ?? safeActionUrl(href);\n const { campaignId, surfaceId } = islandOptions;\n const variantId = state.variantId ?? undefined;\n // A surface-only Cta has no campaignId prop, but the click must still be\n // attributed: the server names the campaign it served in the terminal\n // done.meta, mirroring the impression path in useIsland.\n const metaCampaignId =\n typeof state.meta?.campaignId === \"string\" ? state.meta.campaignId : undefined;\n const resolvedCampaignId = campaignId ?? metaCampaignId;\n\n // The click is the other half of CTR. The SDK tells the server to suppress\n // its own counting for this page view \u2014 so if nothing here reports the\n // click, CTR for SDK traffic is a division by silence. Fire-and-forget:\n // track never throws and never blocks the navigation.\n const handleClick = () => {\n if (resolvedCampaignId) {\n void track(\n { apiBase, organizationId, campaignId: resolvedCampaignId, variantId, surfaceId },\n \"click\",\n { island: \"cta\" },\n );\n }\n onClick?.();\n };\n\n // The hold RESERVES (LAYOUT-DOCTRINE.md): a holding label rides the\n // fallback into StreamText invisibly, so the button keeps the size its\n // label will need. Delete this and the button collapses during the hold.\n const holding = state.phase === \"holding\";\n const ctaReserve = state.held?.cta || islandOptions.fallback.cta;\n const reserved = holding && !!ctaReserve && !state.fields.cta.text;\n const labelField = reserved\n ? withReserve(state.fields.cta, ctaReserve as string)\n : state.fields.cta;\n\n // Shared by the link and the no-destination fallback below.\n const shared = {\n onClick: handleClick,\n className:\n \"inline-flex min-h-11 min-w-40 items-center justify-center rounded-full px-6 font-medium\",\n style: {\n ...themeStyle(state.theme),\n // --st-cta-text is the label ink that reads on the theme's primary, so\n // a light theme can never produce a ghost button.\n ...(state.theme?.colors?.primary\n ? { [\"--st-cta-text\" as string]: readableTextColor(state.theme.colors.primary) }\n : {}),\n },\n // A CTA whose label is still empty is not yet a button a viewer can\n // meaningfully act on \u2014 but it must still occupy its space, or the\n // layout shifts when the copy lands.\n // A reserved button is full-size but its visible label is a hidden\n // reservation outside the a11y tree \u2014 never a NAMELESS control: the\n // reservation text is the honest accessible name.\n \"aria-disabled\": state.fields.cta.text ? undefined : true,\n \"aria-label\": reserved ? (ctaReserve as string) : undefined,\n };\n\n // Neither the stream nor you resolved a destination: render a\n // non-interactive element rather than an inert <a> with no href, which\n // some assistive tech still announces as a link to nowhere. Clicks are\n // still observed \u2014 engagement with the creative counts toward CTR whether\n // or not it navigates.\n if (action === undefined) {\n return (\n <span ref={ref as unknown as (element: HTMLSpanElement | null) => void} {...shared}>\n <StreamText field={labelField} />\n </span>\n );\n }\n\n return (\n <a ref={ref} href={action} {...shared}>\n <StreamText field={labelField} />\n </a>\n );\n}\n";
10
+ //# sourceMappingURL=fixtures-0.5.0.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures-0.5.0.d.ts","sourceRoot":"","sources":["../src/fixtures-0.5.0.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,QAAQ,q6HA2GpB,CAAC;AAEF,eAAO,MAAM,OAAO,yoKA8HnB,CAAC"}
@@ -0,0 +1,243 @@
1
+ /**
2
+ * The files `add` ACTUALLY wrote at v0.5.0, extracted from the tagged
3
+ * registry byte for byte (the same doctrine as the 0.3.0 fixtures in
4
+ * upgrade.test.ts: only the real output can falsify the codemod's `find`
5
+ * claims). Machine-generated from `git show v0.5.0:cli/src/registry.ts` —
6
+ * do not "tidy" these.
7
+ */
8
+ export const HERO_050 = `"use client";
9
+
10
+ import { StreamText, useIsland, withReserve, type UseIslandOptions } from "@sparkletree/react";
11
+ import type { FieldState } from "@sparkletree/react";
12
+ import { themeStyle } from "@sparkletree/core";
13
+
14
+ /**
15
+ * Your hero. Edit freely — this file is yours.
16
+ *
17
+ * What you should NOT need to touch, and what you will not find here: when the
18
+ * copy paints, how long it holds, whether it types or lands composed, and
19
+ * whether it carries the adaptation mark. All of that lives in
20
+ * @sparkletree/core and @sparkletree/react so it can be fixed for you without
21
+ * you re-copying this file.
22
+ *
23
+ * \`fallback\` is required. There is no loading state and no skeleton: if the
24
+ * network is slow or the campaign is unreachable, this copy is what your
25
+ * visitor reads. Write it as if it were the only version — often it is.
26
+ *
27
+ * Requires Tailwind CSS for the default classes — swap them freely.
28
+ */
29
+ export interface HeroProps {
30
+ campaignId: string;
31
+ /** First paint. Real copy, never a placeholder. */
32
+ fallback: UseIslandOptions["fallback"];
33
+ }
34
+
35
+ /**
36
+ * Server-driven URLs are configuration, not trust. Only http(s), mailto and
37
+ * tel absolutes and relative navigations ("/", "./", "#", "?") pass; anything
38
+ * else — javascript:, data:, an unprefixed string — is dropped.
39
+ */
40
+ function safeActionUrl(url: string | null | undefined): string | undefined {
41
+ if (!url) return undefined;
42
+ if (
43
+ (url.startsWith("/") && !url.startsWith("//")) ||
44
+ url.startsWith("./") ||
45
+ url.startsWith("#") ||
46
+ url.startsWith("?")
47
+ ) {
48
+ return url;
49
+ }
50
+ try {
51
+ const protocol = new URL(url).protocol;
52
+ if (["https:", "http:", "mailto:", "tel:"].includes(protocol)) return url;
53
+ } catch {
54
+ // Not a parseable URL at all.
55
+ }
56
+ return undefined;
57
+ }
58
+
59
+ export function Hero({ campaignId, fallback }: HeroProps) {
60
+ const { state, ref } = useIsland({ campaignId, island: "hero", fallback });
61
+ const backgroundImage = safeActionUrl(state.backgroundImage);
62
+
63
+ // The hold RESERVES (LAYOUT-DOCTRINE.md): while the canvas waits, each
64
+ // field carries its fallback so StreamText keeps the geometry invisibly —
65
+ // nothing below the hero moves whichever way the wait ends. Delete this
66
+ // and the section collapses during the hold; it is load-bearing.
67
+ const holding = state.phase === "holding";
68
+ const reserveOf = (name: "greeting" | "headline" | "body") =>
69
+ state.held?.[name] || fallback[name];
70
+ const held = (field: FieldState, reserve?: string) =>
71
+ holding && reserve && !field.text ? withReserve(field, reserve) : field;
72
+
73
+ return (
74
+ <section
75
+ ref={ref}
76
+ className="relative overflow-hidden rounded-2xl p-10"
77
+ style={themeStyle(state.theme)}
78
+ >
79
+ {backgroundImage ? (
80
+ <img
81
+ src={backgroundImage}
82
+ alt=""
83
+ className="absolute inset-0 h-full w-full object-cover"
84
+ />
85
+ ) : null}
86
+
87
+ <div className="relative">
88
+ {state.fields.greeting.text || (holding && reserveOf("greeting")) ? (
89
+ <StreamText
90
+ field={held(state.fields.greeting, reserveOf("greeting"))}
91
+ as="p"
92
+ className="text-sm uppercase tracking-wide opacity-80"
93
+ />
94
+ ) : null}
95
+
96
+ {/* h2 to match the packaged Hero. The heading level is yours: pass
97
+ as="h1" if this section is your page's primary heading. */}
98
+ <StreamText
99
+ field={held(state.fields.headline, reserveOf("headline"))}
100
+ as="h2"
101
+ className="mt-2 text-4xl font-semibold"
102
+ />
103
+
104
+ {state.fields.body.text || (holding && reserveOf("body")) ? (
105
+ <StreamText
106
+ field={held(state.fields.body, reserveOf("body"))}
107
+ as="p"
108
+ className="mt-4 max-w-prose"
109
+ />
110
+ ) : null}
111
+ </div>
112
+ </section>
113
+ );
114
+ }
115
+ `;
116
+ export const CTA_050 = `"use client";
117
+
118
+ import { StreamText, useIsland, useSparkletree, withReserve, type UseIslandOptions } from "@sparkletree/react";
119
+ import { readableTextColor, themeStyle, track } from "@sparkletree/core";
120
+
121
+ /**
122
+ * Your call to action. Edit freely.
123
+ *
124
+ * The button keeps its size while the label streams in, so the surrounding
125
+ * layout does not shift under the visitor's cursor mid-click.
126
+ *
127
+ * Requires Tailwind CSS for the default classes — swap them freely.
128
+ */
129
+ export interface CtaProps extends Omit<UseIslandOptions, "island"> {
130
+ /** Where the button goes when the server has not resolved an action. */
131
+ href?: string;
132
+ onClick?: () => void;
133
+ }
134
+
135
+ /**
136
+ * Server-driven URLs are configuration, not trust. Only http(s), mailto and
137
+ * tel absolutes and relative navigations ("/", "./", "#", "?") pass; anything
138
+ * else — javascript:, data:, an unprefixed string — is dropped.
139
+ */
140
+ function safeActionUrl(url: string | null | undefined): string | undefined {
141
+ if (!url) return undefined;
142
+ if (
143
+ (url.startsWith("/") && !url.startsWith("//")) ||
144
+ url.startsWith("./") ||
145
+ url.startsWith("#") ||
146
+ url.startsWith("?")
147
+ ) {
148
+ return url;
149
+ }
150
+ try {
151
+ const protocol = new URL(url).protocol;
152
+ if (["https:", "http:", "mailto:", "tel:"].includes(protocol)) return url;
153
+ } catch {
154
+ // Not a parseable URL at all.
155
+ }
156
+ return undefined;
157
+ }
158
+
159
+ export function Cta(props: CtaProps) {
160
+ const { href, onClick, ...islandOptions } = props;
161
+ const { apiBase, organizationId } = useSparkletree();
162
+ const { state, ref } = useIsland({ ...islandOptions, island: "cta" });
163
+ // A rejected server action falls back to the href prop you control. The
164
+ // prop is vetted too — the same render path, the same rules, one outcome.
165
+ const action = safeActionUrl(state.ctaAction) ?? safeActionUrl(href);
166
+ const { campaignId, surfaceId } = islandOptions;
167
+ const variantId = state.variantId ?? undefined;
168
+ // A surface-only Cta has no campaignId prop, but the click must still be
169
+ // attributed: the server names the campaign it served in the terminal
170
+ // done.meta, mirroring the impression path in useIsland.
171
+ const metaCampaignId =
172
+ typeof state.meta?.campaignId === "string" ? state.meta.campaignId : undefined;
173
+ const resolvedCampaignId = campaignId ?? metaCampaignId;
174
+
175
+ // The click is the other half of CTR. The SDK tells the server to suppress
176
+ // its own counting for this page view — so if nothing here reports the
177
+ // click, CTR for SDK traffic is a division by silence. Fire-and-forget:
178
+ // track never throws and never blocks the navigation.
179
+ const handleClick = () => {
180
+ if (resolvedCampaignId) {
181
+ void track(
182
+ { apiBase, organizationId, campaignId: resolvedCampaignId, variantId, surfaceId },
183
+ "click",
184
+ { island: "cta" },
185
+ );
186
+ }
187
+ onClick?.();
188
+ };
189
+
190
+ // The hold RESERVES (LAYOUT-DOCTRINE.md): a holding label rides the
191
+ // fallback into StreamText invisibly, so the button keeps the size its
192
+ // label will need. Delete this and the button collapses during the hold.
193
+ const holding = state.phase === "holding";
194
+ const ctaReserve = state.held?.cta || islandOptions.fallback.cta;
195
+ const reserved = holding && !!ctaReserve && !state.fields.cta.text;
196
+ const labelField = reserved
197
+ ? withReserve(state.fields.cta, ctaReserve as string)
198
+ : state.fields.cta;
199
+
200
+ // Shared by the link and the no-destination fallback below.
201
+ const shared = {
202
+ onClick: handleClick,
203
+ className:
204
+ "inline-flex min-h-11 min-w-40 items-center justify-center rounded-full px-6 font-medium",
205
+ style: {
206
+ ...themeStyle(state.theme),
207
+ // --st-cta-text is the label ink that reads on the theme's primary, so
208
+ // a light theme can never produce a ghost button.
209
+ ...(state.theme?.colors?.primary
210
+ ? { ["--st-cta-text" as string]: readableTextColor(state.theme.colors.primary) }
211
+ : {}),
212
+ },
213
+ // A CTA whose label is still empty is not yet a button a viewer can
214
+ // meaningfully act on — but it must still occupy its space, or the
215
+ // layout shifts when the copy lands.
216
+ // A reserved button is full-size but its visible label is a hidden
217
+ // reservation outside the a11y tree — never a NAMELESS control: the
218
+ // reservation text is the honest accessible name.
219
+ "aria-disabled": state.fields.cta.text ? undefined : true,
220
+ "aria-label": reserved ? (ctaReserve as string) : undefined,
221
+ };
222
+
223
+ // Neither the stream nor you resolved a destination: render a
224
+ // non-interactive element rather than an inert <a> with no href, which
225
+ // some assistive tech still announces as a link to nowhere. Clicks are
226
+ // still observed — engagement with the creative counts toward CTR whether
227
+ // or not it navigates.
228
+ if (action === undefined) {
229
+ return (
230
+ <span ref={ref as unknown as (element: HTMLSpanElement | null) => void} {...shared}>
231
+ <StreamText field={labelField} />
232
+ </span>
233
+ );
234
+ }
235
+
236
+ return (
237
+ <a ref={ref} href={action} {...shared}>
238
+ <StreamText field={labelField} />
239
+ </a>
240
+ );
241
+ }
242
+ `;
243
+ //# sourceMappingURL=fixtures-0.5.0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures-0.5.0.js","sourceRoot":"","sources":["../src/fixtures-0.5.0.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2GvB,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8HtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,mCAAmC;IACnC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mDAAmD;IACnD,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAsYD,eAAO,MAAM,QAAQ,EAAE,SAAS,iBAAiB,EAoChD,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEzE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAe5E"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3C,mCAAmC;IACnC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mDAAmD;IACnD,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAsVD,eAAO,MAAM,QAAQ,EAAE,SAAS,iBAAiB,EAoChD,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEzE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAe5E"}
package/dist/registry.js CHANGED
@@ -24,7 +24,7 @@ const HERO_TSX = `"use client";
24
24
 
25
25
  import { StreamText, useIsland, withReserve, type UseIslandOptions } from "@sparkletree/react";
26
26
  import type { FieldState } from "@sparkletree/react";
27
- import { themeStyle } from "@sparkletree/core";
27
+ import { safeActionUrl, themeStyle } from "@sparkletree/core";
28
28
 
29
29
  /**
30
30
  * Your hero. Edit freely — this file is yours.
@@ -49,30 +49,6 @@ export interface HeroProps {
49
49
  fallback: UseIslandOptions["fallback"];
50
50
  }
51
51
 
52
- /**
53
- * Server-driven URLs are configuration, not trust. Only http(s), mailto and
54
- * tel absolutes and relative navigations ("/", "./", "#", "?") pass; anything
55
- * else — javascript:, data:, an unprefixed string — is dropped.
56
- */
57
- function safeActionUrl(url: string | null | undefined): string | undefined {
58
- if (!url) return undefined;
59
- if (
60
- (url.startsWith("/") && !url.startsWith("//")) ||
61
- url.startsWith("./") ||
62
- url.startsWith("#") ||
63
- url.startsWith("?")
64
- ) {
65
- return url;
66
- }
67
- try {
68
- const protocol = new URL(url).protocol;
69
- if (["https:", "http:", "mailto:", "tel:"].includes(protocol)) return url;
70
- } catch {
71
- // Not a parseable URL at all.
72
- }
73
- return undefined;
74
- }
75
-
76
52
  export function Hero({ campaignId, fallback }: HeroProps) {
77
53
  const { state, ref } = useIsland({ campaignId, island: "hero", fallback });
78
54
  const backgroundImage = safeActionUrl(state.backgroundImage);
@@ -133,7 +109,7 @@ export function Hero({ campaignId, fallback }: HeroProps) {
133
109
  const CTA_TSX = `"use client";
134
110
 
135
111
  import { StreamText, useIsland, useSparkletree, withReserve, type UseIslandOptions } from "@sparkletree/react";
136
- import { readableTextColor, themeStyle, track } from "@sparkletree/core";
112
+ import { readableTextColor, safeActionUrl, themeStyle, track } from "@sparkletree/core";
137
113
 
138
114
  /**
139
115
  * Your call to action. Edit freely.
@@ -149,30 +125,6 @@ export interface CtaProps extends Omit<UseIslandOptions, "island"> {
149
125
  onClick?: () => void;
150
126
  }
151
127
 
152
- /**
153
- * Server-driven URLs are configuration, not trust. Only http(s), mailto and
154
- * tel absolutes and relative navigations ("/", "./", "#", "?") pass; anything
155
- * else — javascript:, data:, an unprefixed string — is dropped.
156
- */
157
- function safeActionUrl(url: string | null | undefined): string | undefined {
158
- if (!url) return undefined;
159
- if (
160
- (url.startsWith("/") && !url.startsWith("//")) ||
161
- url.startsWith("./") ||
162
- url.startsWith("#") ||
163
- url.startsWith("?")
164
- ) {
165
- return url;
166
- }
167
- try {
168
- const protocol = new URL(url).protocol;
169
- if (["https:", "http:", "mailto:", "tel:"].includes(protocol)) return url;
170
- } catch {
171
- // Not a parseable URL at all.
172
- }
173
- return undefined;
174
- }
175
-
176
128
  export function Cta(props: CtaProps) {
177
129
  const { href, onClick, ...islandOptions } = props;
178
130
  const { apiBase, organizationId } = useSparkletree();
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
package/dist/upgrade.d.ts CHANGED
@@ -1,42 +1,60 @@
1
1
  /**
2
2
  * `sparkletree upgrade`
3
3
  *
4
- * The 0.3.0 → 0.4.0 codemod for copied components. Copies are the customer's
5
- * files (see registry.ts), so the SDK cannot patch them at runtime — but 0.4.0
6
- * moved the hold from blanking to RESERVING (LAYOUT-DOCTRINE.md), and a copy
7
- * without the reservation wiring still collapses during the hold. This command
8
- * ports that wiring into copies that came from `add` at 0.3.0.
4
+ * Version-aware codemods for copied components. Copies are the customer's
5
+ * files (see registry.ts), so the SDK cannot patch them at runtime; this
6
+ * command ports each GENERATION of template wiring into copies that predate
7
+ * it. A copy from `add` at 0.3.0 gets every generation in order; a 0.5.0
8
+ * copy gets only the generations it is missing. Which generations a copy is
9
+ * missing is decided by content (each generation's marker), never by
10
+ * guessing a version.
9
11
  *
10
12
  * How it stays safe in someone else's repository:
11
13
  *
12
- * - exact-substring hunks, all-or-nothing per file. Every hunk must match
13
- * exactly once (or, where marked, at least once) before anything is
14
- * written. One miss means the file has diverged from the template at a
15
- * line the upgrade needs, and guessing at edited code is how a tool
16
- * "reverts three months of my hero" — so we write nothing and say which
17
- * hunks failed, so the wiring can be ported by hand;
14
+ * - exact-substring hunks, all-or-nothing per file. Every hunk of every
15
+ * needed generation must match exactly once (or, where marked, at least
16
+ * once) before anything is written. One miss means the file has diverged
17
+ * from the template at a line the upgrade needs, and guessing at edited
18
+ * code is how a tool "reverts three months of my hero" — so we write
19
+ * nothing and say which hunks failed, so the wiring can be ported by
20
+ * hand;
18
21
  * - hunks avoid the Tailwind classNames, which `add` explicitly invites
19
22
  * customers to change. A restyled copy still upgrades;
20
- * - idempotent: a file that already has the wiring (it imports
21
- * `withReserve`) is reported up to date and never touched;
23
+ * - idempotent: a generation whose marker is already in the file is
24
+ * skipped, and a copy missing none is reported up to date and never
25
+ * touched;
22
26
  * - `--dry-run` reports the same verdicts and writes nothing.
23
27
  */
24
28
  interface Hunk {
25
29
  /** For the skipped-report: which part of the wiring this is. */
26
30
  label: string;
27
- /** Exact text as `add` wrote it at 0.3.0. */
31
+ /** Exact text as `add` wrote it, byte for byte. */
28
32
  find: string;
29
33
  replace: string;
30
34
  /** Replace every occurrence instead of requiring exactly one. */
31
35
  all?: boolean;
32
36
  }
37
+ interface Codemod {
38
+ /**
39
+ * Already-upgraded detection: presence of this marker means this
40
+ * generation's wiring is in the copy, so the generation is skipped.
41
+ */
42
+ marker: string;
43
+ /**
44
+ * Minimum installed @sparkletree/react (core, react and cli version
45
+ * together) the REWRITTEN copy compiles against. Below it the run behaves
46
+ * as a dry run — writing code an old install cannot compile trades a
47
+ * cosmetic gap for a build error.
48
+ */
49
+ needs: string;
50
+ hunks: Hunk[];
51
+ }
33
52
  export interface UpgradeTarget {
34
53
  component: string;
35
54
  /** Where `add` writes it, relative to the target directory. */
36
55
  path: string;
37
- /** Already-upgraded detection: 0.3.0 copies never mention withReserve. */
38
- marker: string;
39
- hunks: Hunk[];
56
+ /** Oldest first; a copy gets every generation it is missing, in order. */
57
+ codemods: readonly Codemod[];
40
58
  }
41
59
  export declare const UPGRADE_TARGETS: readonly UpgradeTarget[];
42
60
  export interface UpgradeOptions {
@@ -56,13 +74,19 @@ export interface UpgradeResult {
56
74
  hunks: string[];
57
75
  }[];
58
76
  /**
59
- * The installed @sparkletree/react version, when it predates the wiring.
60
- * The upgraded source reads `state.held`, which does not exist before
61
- * 0.4.0 writing it against an old install trades a layout gap for a
62
- * compile error. When set, the run behaved as a dry run: `upgraded` lists
63
- * what WOULD be written once the packages are updated.
77
+ * The installed @sparkletree/react version, when it predates
78
+ * `requiredReact`. Writing code an old install cannot compile trades a
79
+ * cosmetic gap for a build error, so when set the run behaved as a dry
80
+ * run: `upgraded` lists what WOULD be written once the packages are
81
+ * updated.
64
82
  */
65
83
  blockedByReact: string | null;
84
+ /**
85
+ * The highest `needs` among the generations this run wanted to apply —
86
+ * what to update @sparkletree/react (and core) to when blocked. Null when
87
+ * nothing needed upgrading.
88
+ */
89
+ requiredReact: string | null;
66
90
  }
67
91
  export declare function upgrade(options?: UpgradeOptions): Promise<UpgradeResult>;
68
92
  /** Human-readable summary. Mirrors what `upgrade` actually did. */
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,UAAU,IAAI;IACZ,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAsBD,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EA+FnD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yEAAyE;IACzE,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAC9C;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAmCD,wBAAsB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAoDlF;AAED,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,UAAQ,GAAG,MAAM,CA4CjF"}
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,UAAU,IAAI;IACZ,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,UAAU,OAAO;IACf;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;CAC9B;AAsDD,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EA8InD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yEAAyE;IACzE,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAC9C;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAgDD,wBAAsB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CA8ElF;AAED,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,UAAQ,GAAG,MAAM,CA6CjF"}
package/dist/upgrade.js CHANGED
@@ -1,24 +1,28 @@
1
1
  /**
2
2
  * `sparkletree upgrade`
3
3
  *
4
- * The 0.3.0 → 0.4.0 codemod for copied components. Copies are the customer's
5
- * files (see registry.ts), so the SDK cannot patch them at runtime — but 0.4.0
6
- * moved the hold from blanking to RESERVING (LAYOUT-DOCTRINE.md), and a copy
7
- * without the reservation wiring still collapses during the hold. This command
8
- * ports that wiring into copies that came from `add` at 0.3.0.
4
+ * Version-aware codemods for copied components. Copies are the customer's
5
+ * files (see registry.ts), so the SDK cannot patch them at runtime; this
6
+ * command ports each GENERATION of template wiring into copies that predate
7
+ * it. A copy from `add` at 0.3.0 gets every generation in order; a 0.5.0
8
+ * copy gets only the generations it is missing. Which generations a copy is
9
+ * missing is decided by content (each generation's marker), never by
10
+ * guessing a version.
9
11
  *
10
12
  * How it stays safe in someone else's repository:
11
13
  *
12
- * - exact-substring hunks, all-or-nothing per file. Every hunk must match
13
- * exactly once (or, where marked, at least once) before anything is
14
- * written. One miss means the file has diverged from the template at a
15
- * line the upgrade needs, and guessing at edited code is how a tool
16
- * "reverts three months of my hero" — so we write nothing and say which
17
- * hunks failed, so the wiring can be ported by hand;
14
+ * - exact-substring hunks, all-or-nothing per file. Every hunk of every
15
+ * needed generation must match exactly once (or, where marked, at least
16
+ * once) before anything is written. One miss means the file has diverged
17
+ * from the template at a line the upgrade needs, and guessing at edited
18
+ * code is how a tool "reverts three months of my hero" — so we write
19
+ * nothing and say which hunks failed, so the wiring can be ported by
20
+ * hand;
18
21
  * - hunks avoid the Tailwind classNames, which `add` explicitly invites
19
22
  * customers to change. A restyled copy still upgrades;
20
- * - idempotent: a file that already has the wiring (it imports
21
- * `withReserve`) is reported up to date and never touched;
23
+ * - idempotent: a generation whose marker is already in the file is
24
+ * skipped, and a copy missing none is reported up to date and never
25
+ * touched;
22
26
  * - `--dry-run` reports the same verdicts and writes nothing.
23
27
  */
24
28
  import { readFile, writeFile } from "node:fs/promises";
@@ -41,98 +45,176 @@ const CTA_RESERVATION = ` // The hold RESERVES (LAYOUT-DOCTRINE.md): a holding
41
45
  const labelField = reserved
42
46
  ? withReserve(state.fields.cta, ctaReserve as string)
43
47
  : state.fields.cta;`;
48
+ /**
49
+ * The pre-0.6.1 inline vetting helper, byte for byte as `add` wrote it into
50
+ * every hero and cta copy from 0.3.0 through 0.5.0. 0.6.1 moved the one
51
+ * implementation to @sparkletree/core — deleting this block and importing
52
+ * the shared helper IS that generation.
53
+ */
54
+ const INLINE_SAFE_ACTION_URL = `/**
55
+ * Server-driven URLs are configuration, not trust. Only http(s), mailto and
56
+ * tel absolutes and relative navigations ("/", "./", "#", "?") pass; anything
57
+ * else — javascript:, data:, an unprefixed string — is dropped.
58
+ */
59
+ function safeActionUrl(url: string | null | undefined): string | undefined {
60
+ if (!url) return undefined;
61
+ if (
62
+ (url.startsWith("/") && !url.startsWith("//")) ||
63
+ url.startsWith("./") ||
64
+ url.startsWith("#") ||
65
+ url.startsWith("?")
66
+ ) {
67
+ return url;
68
+ }
69
+ try {
70
+ const protocol = new URL(url).protocol;
71
+ if (["https:", "http:", "mailto:", "tel:"].includes(protocol)) return url;
72
+ } catch {
73
+ // Not a parseable URL at all.
74
+ }
75
+ return undefined;
76
+ }
77
+
78
+ `;
44
79
  export const UPGRADE_TARGETS = [
45
80
  {
46
81
  component: "hero",
47
82
  path: "sparkletree/hero.tsx",
48
- marker: "withReserve",
49
- hunks: [
83
+ codemods: [
84
+ {
85
+ // 0.4.0: the hold RESERVES instead of blanking (LAYOUT-DOCTRINE.md).
86
+ marker: "withReserve",
87
+ needs: "0.4.0",
88
+ hunks: [
89
+ {
90
+ label: "imports",
91
+ find: `import { StreamText, useIsland, type UseIslandOptions } from "@sparkletree/react";`,
92
+ replace: `import { StreamText, useIsland, withReserve, type UseIslandOptions } from "@sparkletree/react";
93
+ import type { FieldState } from "@sparkletree/react";`,
94
+ },
95
+ {
96
+ label: "reservation helpers",
97
+ find: `const backgroundImage = safeActionUrl(state.backgroundImage);`,
98
+ replace: `const backgroundImage = safeActionUrl(state.backgroundImage);
99
+
100
+ ${HERO_RESERVATION}`,
101
+ },
102
+ {
103
+ label: "greeting condition",
104
+ find: `{state.fields.greeting.text ? (`,
105
+ replace: `{state.fields.greeting.text || (holding && reserveOf("greeting")) ? (`,
106
+ },
107
+ {
108
+ label: "greeting field",
109
+ find: `field={state.fields.greeting}`,
110
+ replace: `field={held(state.fields.greeting, reserveOf("greeting"))}`,
111
+ },
112
+ {
113
+ label: "headline field",
114
+ find: `field={state.fields.headline}`,
115
+ replace: `field={held(state.fields.headline, reserveOf("headline"))}`,
116
+ },
117
+ {
118
+ label: "body condition",
119
+ find: `{state.fields.body.text ? (`,
120
+ replace: `{state.fields.body.text || (holding && reserveOf("body")) ? (`,
121
+ },
122
+ {
123
+ label: "body field",
124
+ find: `field={state.fields.body}`,
125
+ replace: `field={held(state.fields.body, reserveOf("body"))}`,
126
+ },
127
+ ],
128
+ },
50
129
  {
51
- label: "disclosure note",
52
- find: ` * copy paints, how long it holds, whether it types or lands composed, and
130
+ // 0.6.1: one safeActionUrl, imported from core; the header stops
131
+ // claiming a default disclosure mark is handled upstream.
132
+ marker: `safeActionUrl, themeStyle } from "@sparkletree/core"`,
133
+ needs: "0.6.1",
134
+ hunks: [
135
+ {
136
+ label: "disclosure note",
137
+ find: ` * copy paints, how long it holds, whether it types or lands composed, and
53
138
  * whether it carries the adaptation mark. All of that lives in
54
139
  * @sparkletree/core and @sparkletree/react so it can be fixed for you without
55
140
  * you re-copying this file.`,
56
- replace: ` * copy paints, how long it holds, whether it types or lands composed, and the
141
+ replace: ` * copy paints, how long it holds, whether it types or lands composed, and the
57
142
  * provenance every adapted field carries. All of that lives in
58
143
  * @sparkletree/core and @sparkletree/react so it can be fixed for you without
59
144
  * you re-copying this file. No visible AI-disclosure mark renders by default —
60
145
  * if you want one, render \`InlineMark\` from @sparkletree/react where
61
146
  * \`decideChrome(field.source, prefersStandard).marked\` is true.`,
62
- },
63
- {
64
- label: "imports",
65
- find: `import { StreamText, useIsland, type UseIslandOptions } from "@sparkletree/react";`,
66
- replace: `import { StreamText, useIsland, withReserve, type UseIslandOptions } from "@sparkletree/react";
67
- import type { FieldState } from "@sparkletree/react";`,
68
- },
69
- {
70
- label: "reservation helpers",
71
- find: `const backgroundImage = safeActionUrl(state.backgroundImage);`,
72
- replace: `const backgroundImage = safeActionUrl(state.backgroundImage);
73
-
74
- ${HERO_RESERVATION}`,
75
- },
76
- {
77
- label: "greeting condition",
78
- find: `{state.fields.greeting.text ? (`,
79
- replace: `{state.fields.greeting.text || (holding && reserveOf("greeting")) ? (`,
80
- },
81
- {
82
- label: "greeting field",
83
- find: `field={state.fields.greeting}`,
84
- replace: `field={held(state.fields.greeting, reserveOf("greeting"))}`,
85
- },
86
- {
87
- label: "headline field",
88
- find: `field={state.fields.headline}`,
89
- replace: `field={held(state.fields.headline, reserveOf("headline"))}`,
90
- },
91
- {
92
- label: "body condition",
93
- find: `{state.fields.body.text ? (`,
94
- replace: `{state.fields.body.text || (holding && reserveOf("body")) ? (`,
95
- },
96
- {
97
- label: "body field",
98
- find: `field={state.fields.body}`,
99
- replace: `field={held(state.fields.body, reserveOf("body"))}`,
147
+ },
148
+ {
149
+ label: "core imports",
150
+ find: `import { themeStyle } from "@sparkletree/core";`,
151
+ replace: `import { safeActionUrl, themeStyle } from "@sparkletree/core";`,
152
+ },
153
+ {
154
+ label: "shared safeActionUrl",
155
+ find: INLINE_SAFE_ACTION_URL,
156
+ replace: ``,
157
+ },
158
+ ],
100
159
  },
101
160
  ],
102
161
  },
103
162
  {
104
163
  component: "cta",
105
164
  path: "sparkletree/cta.tsx",
106
- marker: "withReserve",
107
- hunks: [
165
+ codemods: [
108
166
  {
109
- label: "imports",
110
- find: `import { StreamText, useIsland, useSparkletree, type UseIslandOptions } from "@sparkletree/react";`,
111
- replace: `import { StreamText, useIsland, useSparkletree, withReserve, type UseIslandOptions } from "@sparkletree/react";`,
112
- },
113
- {
114
- label: "reservation helpers",
115
- find: ` onClick?.();
167
+ // 0.4.0: the hold RESERVES instead of blanking (LAYOUT-DOCTRINE.md).
168
+ marker: "withReserve",
169
+ needs: "0.4.0",
170
+ hunks: [
171
+ {
172
+ label: "imports",
173
+ find: `import { StreamText, useIsland, useSparkletree, type UseIslandOptions } from "@sparkletree/react";`,
174
+ replace: `import { StreamText, useIsland, useSparkletree, withReserve, type UseIslandOptions } from "@sparkletree/react";`,
175
+ },
176
+ {
177
+ label: "reservation helpers",
178
+ find: ` onClick?.();
116
179
  };`,
117
- replace: ` onClick?.();
180
+ replace: ` onClick?.();
118
181
  };
119
182
 
120
183
  ${CTA_RESERVATION}`,
121
- },
122
- {
123
- label: "accessible name",
124
- find: ` "aria-disabled": state.fields.cta.text ? undefined : true,`,
125
- replace: ` // A reserved button is full-size but its visible label is a hidden
184
+ },
185
+ {
186
+ label: "accessible name",
187
+ find: ` "aria-disabled": state.fields.cta.text ? undefined : true,`,
188
+ replace: ` // A reserved button is full-size but its visible label is a hidden
126
189
  // reservation outside the a11y tree — never a NAMELESS control: the
127
190
  // reservation text is the honest accessible name.
128
191
  "aria-disabled": state.fields.cta.text ? undefined : true,
129
192
  "aria-label": reserved ? (ctaReserve as string) : undefined,`,
193
+ },
194
+ {
195
+ label: "label field",
196
+ find: `<StreamText field={state.fields.cta} />`,
197
+ replace: `<StreamText field={labelField} />`,
198
+ all: true,
199
+ },
200
+ ],
130
201
  },
131
202
  {
132
- label: "label field",
133
- find: `<StreamText field={state.fields.cta} />`,
134
- replace: `<StreamText field={labelField} />`,
135
- all: true,
203
+ // 0.6.1: one safeActionUrl, imported from core.
204
+ marker: `readableTextColor, safeActionUrl, themeStyle, track } from "@sparkletree/core"`,
205
+ needs: "0.6.1",
206
+ hunks: [
207
+ {
208
+ label: "core imports",
209
+ find: `import { readableTextColor, themeStyle, track } from "@sparkletree/core";`,
210
+ replace: `import { readableTextColor, safeActionUrl, themeStyle, track } from "@sparkletree/core";`,
211
+ },
212
+ {
213
+ label: "shared safeActionUrl",
214
+ find: INLINE_SAFE_ACTION_URL,
215
+ replace: ``,
216
+ },
217
+ ],
136
218
  },
137
219
  ],
138
220
  },
@@ -160,25 +242,43 @@ async function installedReactVersion(cwd) {
160
242
  dir = parent;
161
243
  }
162
244
  }
163
- function supportsReservation(version) {
164
- const [major = 0, minor = 0] = version.split(".").map(Number);
165
- // Unparseable versions are not evidence of an old install.
166
- if (!Number.isFinite(major) || !Number.isFinite(minor))
167
- return true;
168
- return major > 0 || minor >= 4;
245
+ /** installed >= needs, on plain major.minor.patch. Unparseable installed
246
+ * versions are not evidence of an old install and pass. */
247
+ function versionAtLeast(installed, needs) {
248
+ const have = installed.split(".").map(Number);
249
+ const want = needs.split(".").map(Number);
250
+ for (let i = 0; i < 3; i++) {
251
+ const a = have[i] ?? 0;
252
+ const b = want[i] ?? 0;
253
+ if (!Number.isFinite(a))
254
+ return true;
255
+ if (a !== b)
256
+ return a > b;
257
+ }
258
+ return true;
259
+ }
260
+ /** The larger of two plain versions, for accumulating `requiredReact`. */
261
+ function maxVersion(a, b) {
262
+ if (a === null)
263
+ return b;
264
+ return versionAtLeast(a, b) ? a : b;
169
265
  }
170
266
  export async function upgrade(options = {}) {
171
267
  const cwd = options.cwd ?? process.cwd();
172
268
  const targetDir = options.targetDir ?? "components";
173
269
  const reactVersion = await installedReactVersion(cwd);
174
- const blockedByReact = reactVersion !== null && !supportsReservation(reactVersion) ? reactVersion : null;
175
270
  const result = {
176
271
  upgraded: [],
177
272
  upToDate: [],
178
273
  missing: [],
179
274
  diverged: [],
180
- blockedByReact,
275
+ blockedByReact: null,
276
+ requiredReact: null,
181
277
  };
278
+ // First pass: which generations does each copy still need? The block
279
+ // decision needs the answer across ALL files — updating packages is one
280
+ // action, so the run names one required version, not one per file.
281
+ const pending = [];
182
282
  for (const target of UPGRADE_TARGETS) {
183
283
  const absolute = resolve(cwd, targetDir, target.path);
184
284
  const path = relative(cwd, absolute);
@@ -190,25 +290,45 @@ export async function upgrade(options = {}) {
190
290
  result.missing.push(path);
191
291
  continue;
192
292
  }
193
- if (content.includes(target.marker)) {
293
+ const needed = target.codemods.filter((codemod) => !content.includes(codemod.marker));
294
+ if (!needed.length) {
194
295
  result.upToDate.push(path);
195
296
  continue;
196
297
  }
197
- const failed = target.hunks
198
- .filter((hunk) => {
199
- const count = occurrences(content, hunk.find);
200
- return hunk.all ? count === 0 : count !== 1;
201
- })
202
- .map((hunk) => hunk.label);
298
+ for (const codemod of needed) {
299
+ result.requiredReact = maxVersion(result.requiredReact, codemod.needs);
300
+ }
301
+ pending.push({ absolute, path, content, needed });
302
+ }
303
+ if (reactVersion !== null &&
304
+ result.requiredReact !== null &&
305
+ !versionAtLeast(reactVersion, result.requiredReact)) {
306
+ result.blockedByReact = reactVersion;
307
+ }
308
+ // Second pass: validate and apply the needed generations IN ORDER against
309
+ // the evolving text — a later generation's hunks land on the earlier
310
+ // generation's output, exactly as they did across real releases. Still
311
+ // all-or-nothing per file: one miss anywhere and nothing is written.
312
+ for (const { absolute, path, content, needed } of pending) {
313
+ let next = content;
314
+ const failed = [];
315
+ for (const codemod of needed) {
316
+ for (const hunk of codemod.hunks) {
317
+ const count = occurrences(next, hunk.find);
318
+ if (hunk.all ? count === 0 : count !== 1) {
319
+ failed.push(hunk.label);
320
+ continue;
321
+ }
322
+ next = hunk.all
323
+ ? next.replaceAll(hunk.find, hunk.replace)
324
+ : next.replace(hunk.find, hunk.replace);
325
+ }
326
+ }
203
327
  if (failed.length) {
204
328
  result.diverged.push({ path, hunks: failed });
205
329
  continue;
206
330
  }
207
- let next = content;
208
- for (const hunk of target.hunks) {
209
- next = hunk.all ? next.replaceAll(hunk.find, hunk.replace) : next.replace(hunk.find, hunk.replace);
210
- }
211
- if (!options.dryRun && !blockedByReact)
331
+ if (!options.dryRun && !result.blockedByReact)
212
332
  await writeFile(absolute, next, "utf8");
213
333
  result.upgraded.push(path);
214
334
  }
@@ -219,10 +339,10 @@ export function formatUpgradeResult(result, dryRun = false) {
219
339
  const lines = [];
220
340
  const verb = dryRun || result.blockedByReact ? "Would upgrade" : "Upgraded";
221
341
  if (result.blockedByReact) {
222
- lines.push(`Nothing written: @sparkletree/react ${result.blockedByReact} is installed,`, "and the reservation wiring needs ^0.4.0 (`state.held` does not exist", "before it). Update @sparkletree/react and @sparkletree/core, then", "re-run `sparkletree upgrade`.", "");
342
+ lines.push(`Nothing written: @sparkletree/react ${result.blockedByReact} is installed,`, `and this upgrade's wiring needs ^${result.requiredReact ?? "0.4.0"} to compile.`, "Update @sparkletree/react and @sparkletree/core, then re-run", "`sparkletree upgrade`.", "");
223
343
  }
224
344
  if (result.upgraded.length) {
225
- lines.push(`${verb} to the 0.4.0 reservation wiring:`);
345
+ lines.push(`${verb} to the current template wiring:`);
226
346
  for (const path of result.upgraded)
227
347
  lines.push(` ${path}`);
228
348
  }
@@ -236,12 +356,12 @@ export function formatUpgradeResult(result, dryRun = false) {
236
356
  for (const item of result.diverged) {
237
357
  lines.push(` ${item.path} — did not match at: ${item.hunks.join(", ")}`);
238
358
  }
239
- lines.push("", "Nothing was written to those files. Port the reservation wiring by", "hand (the current templates show it: `sparkletree add <name> --dir", "/tmp/fresh` writes a reference copy), or re-copy with `add --force`", "if you are happy to lose your edits.");
359
+ lines.push("", "Nothing was written to those files. Port the wiring by hand (the", "current templates show it: `sparkletree add <name> --dir /tmp/fresh`", "writes a reference copy), or re-copy with `add --force` if you are", "happy to lose your edits.");
240
360
  }
241
361
  if (!lines.length) {
242
362
  lines.push("Nothing to upgrade — no copied hero or cta found.");
243
363
  }
244
- lines.push("", "Why: 0.4.0 holds by RESERVING space with the fallback instead of", "rendering nothing. Without this wiring a copied hero or cta collapses", "during the hold and the page shifts when copy arrives.");
364
+ lines.push("", "Why: copies drift. 0.4.0 holds by RESERVING space with the fallback", "(without it a copied hero or cta collapses during the hold), and 0.6.1", "moved URL vetting to one implementation in @sparkletree/core so security", "fixes reach copies through npm instead of a migration guide.");
245
365
  return lines.join("\n");
246
366
  }
247
367
  //# sourceMappingURL=upgrade.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparkletree/cli",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "sparkletree — add SparkleTree components to your project.",
5
5
  "license": "MIT",
6
6
  "type": "module",