@sxl-studio/storybook-addon 1.0.14 → 1.0.15

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/index.d.ts CHANGED
@@ -69,6 +69,10 @@ type SxlRegistry = {
69
69
  figmaFileKey: string;
70
70
  figmaFileName?: string;
71
71
  updatedAt?: string;
72
+ repository?: {
73
+ url?: string;
74
+ documentationUrl?: string;
75
+ };
72
76
  entries: SxlRegistryEntry[];
73
77
  };
74
78
  /**
package/dist/index.js CHANGED
@@ -11,12 +11,17 @@ function fromDiffCodeConnect(data) {
11
11
  const d = data;
12
12
  const fileKey = typeof d.$figmaFileKey === "string" ? d.$figmaFileKey : "";
13
13
  const fileName = typeof d.$figmaFileName === "string" ? d.$figmaFileName : void 0;
14
+ const repository = d.repository && typeof d.repository === "object" ? d.repository : void 0;
14
15
  const isV2 = Array.isArray(d.components);
15
16
  const entries = isV2 ? convertV2Components(d.components, fileKey) : convertV1Entries(Array.isArray(d.entries) ? d.entries : [], fileKey);
16
17
  return {
17
18
  version: 1,
18
19
  figmaFileKey: fileKey,
19
20
  figmaFileName: fileName,
21
+ repository: repository ? {
22
+ ...typeof repository.url === "string" ? { url: repository.url } : {},
23
+ ...typeof repository.documentationUrl === "string" ? { documentationUrl: repository.documentationUrl } : {}
24
+ } : void 0,
20
25
  entries
21
26
  };
22
27
  }
@@ -133,6 +138,54 @@ function joinFetchUrl(base, path) {
133
138
  const segments = normalizeCompositionPath(path).split("/").filter(Boolean);
134
139
  return b + segments.map(encodeURIComponent).join("/");
135
140
  }
141
+ function candidateRelativePaths(path) {
142
+ const n = normalizeCompositionPath(path);
143
+ const out = [n];
144
+ if (n.startsWith("components/")) {
145
+ out.push(n.slice("components/".length));
146
+ }
147
+ return Array.from(new Set(out));
148
+ }
149
+ function buildGitlabRawCandidates(repositoryUrl, path) {
150
+ let parsed;
151
+ try {
152
+ parsed = new URL(repositoryUrl);
153
+ } catch {
154
+ return [];
155
+ }
156
+ const cleanPath = parsed.pathname.replace(/\/+$/, "");
157
+ const marker = "/-/tree/";
158
+ const idx = cleanPath.indexOf(marker);
159
+ if (idx < 0) return [];
160
+ const prefix = cleanPath.slice(0, idx);
161
+ const tail = cleanPath.slice(idx + marker.length);
162
+ const slash = tail.indexOf("/");
163
+ const ref = slash >= 0 ? tail.slice(0, slash) : tail;
164
+ const baseDir = slash >= 0 ? tail.slice(slash + 1) : "";
165
+ const baseRaw = `${parsed.origin}${prefix}/-/raw/${encodeURIComponent(ref)}` + (baseDir ? `/${baseDir.split("/").map(encodeURIComponent).join("/")}` : "");
166
+ return candidateRelativePaths(path).map((rel) => joinFetchUrl(baseRaw, rel));
167
+ }
168
+ function extractRepositoryUrl(params) {
169
+ const raw = params?.registry;
170
+ if (!raw || typeof raw !== "object") return void 0;
171
+ const repo = raw.repository;
172
+ if (!repo || typeof repo !== "object") return void 0;
173
+ const url = repo.url;
174
+ return typeof url === "string" && url.trim() ? url.trim() : void 0;
175
+ }
176
+ async function fetchFirstOk(urls) {
177
+ for (const url of urls) {
178
+ try {
179
+ const res = await fetch(url, { credentials: "include" });
180
+ if (!res.ok) continue;
181
+ const text = await res.text();
182
+ if (!text.trim()) continue;
183
+ return { text, url };
184
+ } catch {
185
+ }
186
+ }
187
+ return null;
188
+ }
136
189
  async function loadCompositionJsonText(path, legacyInline, params) {
137
190
  const inline = legacyInline?.trim();
138
191
  if (inline) {
@@ -176,8 +229,21 @@ async function loadCompositionJsonText(path, legacyInline, params) {
176
229
  return { error: `Fetch failed: ${msg}` };
177
230
  }
178
231
  }
232
+ const repoUrl = extractRepositoryUrl(params);
233
+ if (repoUrl) {
234
+ const gitlabCandidates = buildGitlabRawCandidates(repoUrl, p);
235
+ const hit = await fetchFirstOk(gitlabCandidates);
236
+ if (hit) {
237
+ return { text: hit.text, source: "fetch" };
238
+ }
239
+ }
240
+ const localCandidates = candidateRelativePaths(p).map((rel) => `/${rel}`);
241
+ const localHit = await fetchFirstOk(localCandidates);
242
+ if (localHit) {
243
+ return { text: localHit.text, source: "fetch" };
244
+ }
179
245
  return {
180
- error: "Composition file is not inlined. Pass parameters.sxl.compositionSources, compositionFetchBaseUrl + staticDirs, or resolveComposition() in preview \u2014 see @sxl-studio/storybook-addon README."
246
+ error: "Composition file is not inlined and auto-fetch failed. Pass parameters.sxl.compositionSources, compositionFetchBaseUrl + staticDirs, or resolveComposition() in preview \u2014 see @sxl-studio/storybook-addon README."
181
247
  };
182
248
  }
183
249
  export {
package/dist/manager.js CHANGED
@@ -19,12 +19,17 @@ function fromDiffCodeConnect(data) {
19
19
  const d = data;
20
20
  const fileKey = typeof d.$figmaFileKey === "string" ? d.$figmaFileKey : "";
21
21
  const fileName = typeof d.$figmaFileName === "string" ? d.$figmaFileName : void 0;
22
+ const repository = d.repository && typeof d.repository === "object" ? d.repository : void 0;
22
23
  const isV2 = Array.isArray(d.components);
23
24
  const entries = isV2 ? convertV2Components(d.components, fileKey) : convertV1Entries(Array.isArray(d.entries) ? d.entries : [], fileKey);
24
25
  return {
25
26
  version: 1,
26
27
  figmaFileKey: fileKey,
27
28
  figmaFileName: fileName,
29
+ repository: repository ? {
30
+ ...typeof repository.url === "string" ? { url: repository.url } : {},
31
+ ...typeof repository.documentationUrl === "string" ? { documentationUrl: repository.documentationUrl } : {}
32
+ } : void 0,
28
33
  entries
29
34
  };
30
35
  }
@@ -141,6 +146,54 @@ function joinFetchUrl(base, path) {
141
146
  const segments = normalizeCompositionPath(path).split("/").filter(Boolean);
142
147
  return b + segments.map(encodeURIComponent).join("/");
143
148
  }
149
+ function candidateRelativePaths(path) {
150
+ const n = normalizeCompositionPath(path);
151
+ const out = [n];
152
+ if (n.startsWith("components/")) {
153
+ out.push(n.slice("components/".length));
154
+ }
155
+ return Array.from(new Set(out));
156
+ }
157
+ function buildGitlabRawCandidates(repositoryUrl, path) {
158
+ let parsed;
159
+ try {
160
+ parsed = new URL(repositoryUrl);
161
+ } catch {
162
+ return [];
163
+ }
164
+ const cleanPath = parsed.pathname.replace(/\/+$/, "");
165
+ const marker = "/-/tree/";
166
+ const idx = cleanPath.indexOf(marker);
167
+ if (idx < 0) return [];
168
+ const prefix = cleanPath.slice(0, idx);
169
+ const tail = cleanPath.slice(idx + marker.length);
170
+ const slash = tail.indexOf("/");
171
+ const ref = slash >= 0 ? tail.slice(0, slash) : tail;
172
+ const baseDir = slash >= 0 ? tail.slice(slash + 1) : "";
173
+ const baseRaw = `${parsed.origin}${prefix}/-/raw/${encodeURIComponent(ref)}` + (baseDir ? `/${baseDir.split("/").map(encodeURIComponent).join("/")}` : "");
174
+ return candidateRelativePaths(path).map((rel) => joinFetchUrl(baseRaw, rel));
175
+ }
176
+ function extractRepositoryUrl(params) {
177
+ const raw = params?.registry;
178
+ if (!raw || typeof raw !== "object") return void 0;
179
+ const repo = raw.repository;
180
+ if (!repo || typeof repo !== "object") return void 0;
181
+ const url = repo.url;
182
+ return typeof url === "string" && url.trim() ? url.trim() : void 0;
183
+ }
184
+ async function fetchFirstOk(urls) {
185
+ for (const url of urls) {
186
+ try {
187
+ const res = await fetch(url, { credentials: "include" });
188
+ if (!res.ok) continue;
189
+ const text = await res.text();
190
+ if (!text.trim()) continue;
191
+ return { text, url };
192
+ } catch {
193
+ }
194
+ }
195
+ return null;
196
+ }
144
197
  async function loadCompositionJsonText(path, legacyInline, params) {
145
198
  const inline = legacyInline?.trim();
146
199
  if (inline) {
@@ -184,8 +237,21 @@ async function loadCompositionJsonText(path, legacyInline, params) {
184
237
  return { error: `Fetch failed: ${msg}` };
185
238
  }
186
239
  }
240
+ const repoUrl = extractRepositoryUrl(params);
241
+ if (repoUrl) {
242
+ const gitlabCandidates = buildGitlabRawCandidates(repoUrl, p);
243
+ const hit = await fetchFirstOk(gitlabCandidates);
244
+ if (hit) {
245
+ return { text: hit.text, source: "fetch" };
246
+ }
247
+ }
248
+ const localCandidates = candidateRelativePaths(p).map((rel) => `/${rel}`);
249
+ const localHit = await fetchFirstOk(localCandidates);
250
+ if (localHit) {
251
+ return { text: localHit.text, source: "fetch" };
252
+ }
187
253
  return {
188
- error: "Composition file is not inlined. Pass parameters.sxl.compositionSources, compositionFetchBaseUrl + staticDirs, or resolveComposition() in preview \u2014 see @sxl-studio/storybook-addon README."
254
+ error: "Composition file is not inlined and auto-fetch failed. Pass parameters.sxl.compositionSources, compositionFetchBaseUrl + staticDirs, or resolveComposition() in preview \u2014 see @sxl-studio/storybook-addon README."
189
255
  };
190
256
  }
191
257
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sxl-studio/storybook-addon",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "Storybook addon for SXL Studio — displays Figma Embed, component info and design token status for linked components",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",