@cavuno/board 1.41.0 → 1.42.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.
Files changed (48) hide show
  1. package/dist/{_spec-l_596ZwW.d.mts → _spec-LdkTxfx0.d.mts} +33 -0
  2. package/dist/{_spec-l_596ZwW.d.ts → _spec-LdkTxfx0.d.ts} +33 -0
  3. package/dist/{board-CyHA6rRP.d.mts → board-Cs93Lf23.d.mts} +1 -1
  4. package/dist/{board-BzK5j73O.d.ts → board-FxC9Wdhi.d.ts} +1 -1
  5. package/dist/filters.d.mts +2 -2
  6. package/dist/filters.d.ts +2 -2
  7. package/dist/format.d.mts +3 -3
  8. package/dist/format.d.ts +3 -3
  9. package/dist/go.d.mts +65 -0
  10. package/dist/go.d.ts +65 -0
  11. package/dist/go.js +130 -0
  12. package/dist/go.mjs +107 -0
  13. package/dist/index.d.mts +9 -9
  14. package/dist/index.d.ts +9 -9
  15. package/dist/index.js +1 -1
  16. package/dist/index.mjs +1 -1
  17. package/dist/{jobs-BhthvMkA.d.mts → jobs-BtazrWfv.d.mts} +1 -1
  18. package/dist/{jobs-CXudz1Y4.d.ts → jobs-TIAPH3Ol.d.ts} +1 -1
  19. package/dist/paths.d.mts +25 -1
  20. package/dist/paths.d.ts +25 -1
  21. package/dist/paths.js +20 -1
  22. package/dist/paths.mjs +20 -1
  23. package/dist/roles-vY0AXhoc.d.mts +82 -0
  24. package/dist/roles-vY0AXhoc.d.ts +82 -0
  25. package/dist/route-contract.d.mts +257 -0
  26. package/dist/route-contract.d.ts +257 -0
  27. package/dist/route-contract.js +1131 -0
  28. package/dist/route-contract.mjs +1108 -0
  29. package/dist/{salaries-ByBuHCLH.d.ts → salaries-BEAqkaFt.d.ts} +2 -2
  30. package/dist/{salaries-Dr_Zugal.d.mts → salaries-CB9Ve4kS.d.mts} +2 -2
  31. package/dist/{search-DZrq-k76.d.ts → search-DWmHHXn8.d.ts} +1 -1
  32. package/dist/{search-CrIlXSJP.d.mts → search-YhoVpXFY.d.mts} +1 -1
  33. package/dist/seo.d.mts +4 -4
  34. package/dist/seo.d.ts +4 -4
  35. package/dist/server.d.mts +5 -5
  36. package/dist/server.d.ts +5 -5
  37. package/dist/sitemap.d.mts +5 -5
  38. package/dist/sitemap.d.ts +5 -5
  39. package/dist/sitemap.js +8 -1
  40. package/dist/sitemap.mjs +8 -1
  41. package/dist/suggest.d.mts +2 -2
  42. package/dist/suggest.d.ts +2 -2
  43. package/dist/well-known.d.mts +113 -0
  44. package/dist/well-known.d.ts +113 -0
  45. package/dist/well-known.js +561 -0
  46. package/dist/well-known.mjs +538 -0
  47. package/package.json +31 -1
  48. package/skills/manifest.json +1 -1
@@ -0,0 +1,538 @@
1
+ // src/paths/index.ts
2
+ function jobDetailPath(companySlug, jobSlug) {
3
+ return `/companies/${companySlug}/jobs/${jobSlug}`;
4
+ }
5
+ function jobsCategoryPath(categorySlug) {
6
+ return `/jobs/${categorySlug}`;
7
+ }
8
+ function jobsSkillPath(skillSlug) {
9
+ return `/jobs/skills/${skillSlug}`;
10
+ }
11
+ function jobsLocationPath(placeSlug) {
12
+ return `/jobs/locations/${placeSlug}`;
13
+ }
14
+ function companyPath(companySlug) {
15
+ return `/companies/${companySlug}`;
16
+ }
17
+ function companyMarketPath(marketSlug) {
18
+ return `/companies/markets/${marketSlug}`;
19
+ }
20
+ function companySalaryPath(companySlug) {
21
+ return `/companies/${companySlug}/salaries`;
22
+ }
23
+ function salaryTitlePath(titleSlug) {
24
+ return `/salaries/titles/${titleSlug}`;
25
+ }
26
+ function salarySkillPath(skillSlug) {
27
+ return `/salaries/skills/${skillSlug}`;
28
+ }
29
+ function salaryLocationPath(placeSlug) {
30
+ return `/salaries/locations/${placeSlug}`;
31
+ }
32
+ function blogPostPath(postSlug) {
33
+ return `/blog/${postSlug}`;
34
+ }
35
+ function blogTagPath(tagSlug) {
36
+ return `/blog/tag/${tagSlug}`;
37
+ }
38
+ function blogAuthorPath(authorSlug) {
39
+ return `/blog/author/${authorSlug}`;
40
+ }
41
+ var BOARD_PATHS = {
42
+ home: "/",
43
+ jobs: "/jobs",
44
+ companies: "/companies",
45
+ salaries: "/salaries",
46
+ salaryCompanies: "/salaries/companies",
47
+ salaryTitles: "/salaries/titles",
48
+ salarySkills: "/salaries/skills",
49
+ salaryLocations: "/salaries/locations",
50
+ blog: "/blog",
51
+ about: "/about",
52
+ privacyPolicy: "/privacy-policy",
53
+ termsOfService: "/terms-of-service",
54
+ cookiePolicy: "/cookie-policy",
55
+ impressum: "/impressum",
56
+ talent: "/talent",
57
+ employers: "/employers",
58
+ /**
59
+ * Alert-email surfaces (ADR-0090 D1/D4). Promoted out of raw literals in
60
+ * the job-alerts composer so /go indirection and email composition share
61
+ * one definition.
62
+ */
63
+ alertsManage: "/alerts/manage",
64
+ alertsConfirm: "/alerts/confirm"
65
+ };
66
+
67
+ // src/route-contract/roles.ts
68
+ var ROLE_PARAM_REGISTRY = {
69
+ jobDetail: ["companySlug", "jobSlug"],
70
+ jobsCategory: ["categorySlug"],
71
+ jobsSkill: ["skillSlug"],
72
+ jobsLocation: ["placeSlug"],
73
+ company: ["companySlug"],
74
+ companyMarket: ["marketSlug"],
75
+ companySalary: ["companySlug"],
76
+ salaryTitle: ["titleSlug"],
77
+ salarySkill: ["skillSlug"],
78
+ salaryLocation: ["placeSlug"],
79
+ blogPost: ["postSlug"],
80
+ blogTag: ["tagSlug"],
81
+ blogAuthor: ["authorSlug"],
82
+ home: [],
83
+ jobs: [],
84
+ companies: [],
85
+ salaries: [],
86
+ salaryCompanies: [],
87
+ salaryTitles: [],
88
+ salarySkills: [],
89
+ salaryLocations: [],
90
+ blog: [],
91
+ about: [],
92
+ privacyPolicy: [],
93
+ termsOfService: [],
94
+ cookiePolicy: [],
95
+ impressum: [],
96
+ talent: [],
97
+ employers: [],
98
+ alertsManage: [],
99
+ alertsConfirm: []
100
+ };
101
+ var REQUIRED_ROLES = [
102
+ "jobDetail",
103
+ "alertsManage",
104
+ "alertsConfirm"
105
+ ];
106
+ var ALL_ROLES = Object.keys(
107
+ ROLE_PARAM_REGISTRY
108
+ );
109
+ var ROLE_SET = new Set(ALL_ROLES);
110
+ var CANONICAL_MANIFEST = {
111
+ version: 1,
112
+ roles: {
113
+ jobDetail: jobDetailPath(":companySlug", ":jobSlug"),
114
+ jobsCategory: jobsCategoryPath(":categorySlug"),
115
+ jobsSkill: jobsSkillPath(":skillSlug"),
116
+ jobsLocation: jobsLocationPath(":placeSlug"),
117
+ company: companyPath(":companySlug"),
118
+ companyMarket: companyMarketPath(":marketSlug"),
119
+ companySalary: companySalaryPath(":companySlug"),
120
+ salaryTitle: salaryTitlePath(":titleSlug"),
121
+ salarySkill: salarySkillPath(":skillSlug"),
122
+ salaryLocation: salaryLocationPath(":placeSlug"),
123
+ blogPost: blogPostPath(":postSlug"),
124
+ blogTag: blogTagPath(":tagSlug"),
125
+ blogAuthor: blogAuthorPath(":authorSlug"),
126
+ home: BOARD_PATHS.home,
127
+ jobs: BOARD_PATHS.jobs,
128
+ companies: BOARD_PATHS.companies,
129
+ salaries: BOARD_PATHS.salaries,
130
+ salaryCompanies: BOARD_PATHS.salaryCompanies,
131
+ salaryTitles: BOARD_PATHS.salaryTitles,
132
+ salarySkills: BOARD_PATHS.salarySkills,
133
+ salaryLocations: BOARD_PATHS.salaryLocations,
134
+ blog: BOARD_PATHS.blog,
135
+ about: BOARD_PATHS.about,
136
+ privacyPolicy: BOARD_PATHS.privacyPolicy,
137
+ termsOfService: BOARD_PATHS.termsOfService,
138
+ cookiePolicy: BOARD_PATHS.cookiePolicy,
139
+ impressum: BOARD_PATHS.impressum,
140
+ talent: BOARD_PATHS.talent,
141
+ employers: BOARD_PATHS.employers,
142
+ alertsManage: "/alerts/manage",
143
+ alertsConfirm: "/alerts/confirm"
144
+ }
145
+ };
146
+
147
+ // src/route-contract/params.ts
148
+ function extractParamNames(template) {
149
+ const names = [];
150
+ const re = /:([A-Za-z_][A-Za-z0-9_]*)/g;
151
+ let match;
152
+ while ((match = re.exec(template)) !== null) {
153
+ const name = match[1];
154
+ if (name !== void 0) names.push(name);
155
+ }
156
+ return names;
157
+ }
158
+ function sameParamSet(a, b) {
159
+ if (a.length !== b.length) return false;
160
+ const sortedA = [...a].sort();
161
+ const sortedB = [...b].sort();
162
+ for (let i = 0; i < sortedA.length; i++) {
163
+ if (sortedA[i] !== sortedB[i]) return false;
164
+ }
165
+ return true;
166
+ }
167
+ function paramSetKey(params) {
168
+ return [...params].sort().join("\0");
169
+ }
170
+
171
+ // src/route-contract/classify.ts
172
+ var SHARED_SIGNATURE_COUNTS = (() => {
173
+ const counts = /* @__PURE__ */ new Map();
174
+ for (const role of ALL_ROLES) {
175
+ const params = ROLE_PARAM_REGISTRY[role];
176
+ if (params.length === 0) continue;
177
+ const key = paramSetKey(params);
178
+ counts.set(key, (counts.get(key) ?? 0) + 1);
179
+ }
180
+ return counts;
181
+ })();
182
+ function isSignatureCandidate(route, role) {
183
+ const registry = ROLE_PARAM_REGISTRY[role];
184
+ const routeParams = extractParamNames(route.template);
185
+ if (registry.length === 0) {
186
+ return route.template === CANONICAL_MANIFEST.roles[role];
187
+ }
188
+ if (!sameParamSet(routeParams, registry)) return false;
189
+ const shareCount = SHARED_SIGNATURE_COUNTS.get(paramSetKey(registry)) ?? 0;
190
+ if (shareCount > 1) {
191
+ return route.template === CANONICAL_MANIFEST.roles[role];
192
+ }
193
+ return true;
194
+ }
195
+ function classifyRoutes(routes, markers) {
196
+ const assignments = {};
197
+ const ambiguities = [];
198
+ const claimed = /* @__PURE__ */ new Set();
199
+ if (markers && markers.size > 0) {
200
+ const claimsByRole = /* @__PURE__ */ new Map();
201
+ for (const route of routes) {
202
+ if (route.sourcePath === void 0) continue;
203
+ const role = markers.get(route.sourcePath);
204
+ if (role === void 0) continue;
205
+ const list = claimsByRole.get(role);
206
+ if (list) list.push(route);
207
+ else claimsByRole.set(role, [route]);
208
+ }
209
+ for (const [role, candidates] of claimsByRole) {
210
+ for (const c of candidates) claimed.add(c);
211
+ if (candidates.length === 1) {
212
+ assignments[role] = candidates[0];
213
+ } else {
214
+ ambiguities.push({ role, candidates: [...candidates] });
215
+ }
216
+ }
217
+ }
218
+ const pool = routes.filter((r) => !claimed.has(r));
219
+ for (const role of ALL_ROLES) {
220
+ if (assignments[role] !== void 0) continue;
221
+ if (ambiguities.some((a) => a.role === role)) continue;
222
+ const candidates = pool.filter((r) => isSignatureCandidate(r, role));
223
+ if (candidates.length === 0) continue;
224
+ if (candidates.length === 1) {
225
+ const only = candidates[0];
226
+ if (claimed.has(only)) {
227
+ continue;
228
+ }
229
+ assignments[role] = only;
230
+ claimed.add(only);
231
+ continue;
232
+ }
233
+ ambiguities.push({ role, candidates: [...candidates] });
234
+ }
235
+ const missingRequired = REQUIRED_ROLES.filter(
236
+ (role) => assignments[role] === void 0
237
+ );
238
+ return { assignments, ambiguities, missingRequired };
239
+ }
240
+
241
+ // src/route-contract/validate.ts
242
+ var TEMPLATE_CHARSET_RE = /^[A-Za-z0-9/_.:-]+$/;
243
+ function checkRoleTemplate(role, template) {
244
+ const errors = [];
245
+ if (typeof template !== "string" || template.length === 0) {
246
+ errors.push({
247
+ code: "invalid_template",
248
+ message: `role '${role}' template must be a non-empty string`,
249
+ role
250
+ });
251
+ return errors;
252
+ }
253
+ if (!template.startsWith("/")) {
254
+ errors.push({
255
+ code: "invalid_template",
256
+ message: `role '${role}' template must start with '/', got ${JSON.stringify(template)}`,
257
+ role
258
+ });
259
+ return errors;
260
+ }
261
+ if (/\s/.test(template)) {
262
+ errors.push({
263
+ code: "invalid_template",
264
+ message: `role '${role}' template must not contain whitespace, got ${JSON.stringify(template)}`,
265
+ role
266
+ });
267
+ return errors;
268
+ }
269
+ if (template.includes("?") || template.includes("#")) {
270
+ errors.push({
271
+ code: "template_query_or_fragment",
272
+ message: `role '${role}' template must not contain '?' or '#', got ${JSON.stringify(template)}`,
273
+ role
274
+ });
275
+ return errors;
276
+ }
277
+ if (template.startsWith("//") || template.includes("//")) {
278
+ errors.push({
279
+ code: "template_double_slash",
280
+ message: `role '${role}' template must not contain '//', got ${JSON.stringify(template)}`,
281
+ role
282
+ });
283
+ return errors;
284
+ }
285
+ for (const seg of template.split("/")) {
286
+ if (seg === "." || seg === "..") {
287
+ errors.push({
288
+ code: "template_dot_segment",
289
+ message: `role '${role}' template must not contain '.' or '..' segments, got ${JSON.stringify(template)}`,
290
+ role
291
+ });
292
+ return errors;
293
+ }
294
+ }
295
+ if (!TEMPLATE_CHARSET_RE.test(template)) {
296
+ errors.push({
297
+ code: "template_illegal_charset",
298
+ message: `role '${role}' template contains illegal characters, got ${JSON.stringify(template)}`,
299
+ role
300
+ });
301
+ return errors;
302
+ }
303
+ const registry = ROLE_PARAM_REGISTRY[role];
304
+ const tokens = extractParamNames(template);
305
+ if (registry.length === 0) {
306
+ if (tokens.length > 0) {
307
+ errors.push({
308
+ code: "static_has_params",
309
+ message: `static role '${role}' template must not contain ':' tokens, got ${template}`,
310
+ role,
311
+ token: tokens[0]
312
+ });
313
+ }
314
+ } else {
315
+ const registrySet = new Set(registry);
316
+ for (const token of tokens) {
317
+ if (!registrySet.has(token)) {
318
+ errors.push({
319
+ code: "unregistered_param",
320
+ message: `role '${role}' template references unregistered param ':${token}'`,
321
+ role,
322
+ token
323
+ });
324
+ }
325
+ }
326
+ const retained = tokens.filter((t) => registrySet.has(t));
327
+ if (retained.length === 0) {
328
+ errors.push({
329
+ code: "missing_entity_param",
330
+ message: `role '${role}' template must contain at least one registry param (${registry.join(", ")})`,
331
+ role
332
+ });
333
+ }
334
+ }
335
+ return errors;
336
+ }
337
+
338
+ // src/route-contract/compile.ts
339
+ var REQUIRED_SET = new Set(REQUIRED_ROLES);
340
+ function compileManifest(routes, markers) {
341
+ const { assignments, ambiguities, missingRequired } = classifyRoutes(
342
+ routes,
343
+ markers
344
+ );
345
+ const roles = {};
346
+ const warnings = [];
347
+ const blocking = new Set(missingRequired);
348
+ for (const role of ALL_ROLES) {
349
+ const entry = assignments[role];
350
+ if (entry === void 0) continue;
351
+ const templateErrors = checkRoleTemplate(role, entry.template);
352
+ if (templateErrors.length > 0) {
353
+ const exact = templateErrors.map((e) => e.message).join("; ");
354
+ warnings.push(
355
+ `role '${role}' template rejected: ${exact} \u2014 add export const cavunoPage = '${role}' on the correct page or fix the template`
356
+ );
357
+ if (REQUIRED_SET.has(role)) {
358
+ blocking.add(role);
359
+ }
360
+ continue;
361
+ }
362
+ roles[role] = entry.template;
363
+ }
364
+ for (const amb of ambiguities) {
365
+ const kind = REQUIRED_SET.has(amb.role) ? "required" : "optional";
366
+ warnings.push(
367
+ `${kind} role '${amb.role}' is ambiguous \u2014 add export const cavunoPage = '${amb.role}' to disambiguate`
368
+ );
369
+ }
370
+ for (const role of ALL_ROLES) {
371
+ if (REQUIRED_SET.has(role)) continue;
372
+ if (roles[role] !== void 0) continue;
373
+ if (assignments[role] !== void 0) continue;
374
+ if (ambiguities.some((a) => a.role === role)) continue;
375
+ warnings.push(`optional role '${role}' is unassigned`);
376
+ }
377
+ return {
378
+ manifest: { version: 1, roles },
379
+ blockingMissing: REQUIRED_ROLES.filter((r) => blocking.has(r)),
380
+ warnings,
381
+ ambiguities
382
+ };
383
+ }
384
+
385
+ // src/route-contract/resolve-links.ts
386
+ var REQUIRED_SET2 = new Set(REQUIRED_ROLES);
387
+
388
+ // src/route-contract/match-history.ts
389
+ var ROLE_INDEX_PATHS = {
390
+ jobDetail: BOARD_PATHS.jobs,
391
+ jobsCategory: BOARD_PATHS.jobs,
392
+ jobsSkill: BOARD_PATHS.jobs,
393
+ jobsLocation: BOARD_PATHS.jobs,
394
+ company: BOARD_PATHS.companies,
395
+ companyMarket: BOARD_PATHS.companies,
396
+ companySalary: BOARD_PATHS.companies,
397
+ salaryTitle: BOARD_PATHS.salaries,
398
+ salarySkill: BOARD_PATHS.salaries,
399
+ salaryLocation: BOARD_PATHS.salaries,
400
+ salaryCompanies: BOARD_PATHS.salaries,
401
+ salaryTitles: BOARD_PATHS.salaries,
402
+ salarySkills: BOARD_PATHS.salaries,
403
+ salaryLocations: BOARD_PATHS.salaries,
404
+ salaries: BOARD_PATHS.salaries,
405
+ blogPost: BOARD_PATHS.blog,
406
+ blogTag: BOARD_PATHS.blog,
407
+ blogAuthor: BOARD_PATHS.blog,
408
+ blog: BOARD_PATHS.blog,
409
+ home: BOARD_PATHS.home,
410
+ jobs: BOARD_PATHS.jobs,
411
+ companies: BOARD_PATHS.companies,
412
+ about: BOARD_PATHS.about,
413
+ privacyPolicy: BOARD_PATHS.privacyPolicy,
414
+ termsOfService: BOARD_PATHS.termsOfService,
415
+ cookiePolicy: BOARD_PATHS.cookiePolicy,
416
+ impressum: BOARD_PATHS.impressum,
417
+ talent: BOARD_PATHS.talent,
418
+ employers: BOARD_PATHS.employers,
419
+ alertsManage: BOARD_PATHS.home,
420
+ alertsConfirm: BOARD_PATHS.home
421
+ };
422
+
423
+ // src/well-known/handler.ts
424
+ var WELL_KNOWN_CACHE_CONTROL = "public, max-age=300";
425
+ var WELL_KNOWN_CONTENT_TYPE = "application/json";
426
+ function createWellKnownHandler(config) {
427
+ return async (_request) => {
428
+ try {
429
+ const routes = await resolveRoutes(config.routes);
430
+ const { manifest } = compileManifest(routes, config.markers);
431
+ const body = serializeManifest(manifest);
432
+ return new Response(body, {
433
+ status: 200,
434
+ headers: {
435
+ "content-type": WELL_KNOWN_CONTENT_TYPE,
436
+ "cache-control": WELL_KNOWN_CACHE_CONTROL
437
+ }
438
+ });
439
+ } catch {
440
+ return new Response("", { status: 500 });
441
+ }
442
+ };
443
+ }
444
+ async function resolveRoutes(routes) {
445
+ if (typeof routes === "function") {
446
+ return await routes();
447
+ }
448
+ return routes;
449
+ }
450
+ function serializeManifest(manifest) {
451
+ return JSON.stringify(manifest);
452
+ }
453
+
454
+ // src/well-known/emit.ts
455
+ var WELL_KNOWN_MANIFEST_PATH = ".well-known/cavuno.json";
456
+ function emitWellKnownManifest(config) {
457
+ const { manifest } = compileManifest(config.routes, config.markers);
458
+ const contents = serializeManifest(manifest);
459
+ return { path: WELL_KNOWN_MANIFEST_PATH, contents };
460
+ }
461
+
462
+ // src/well-known/tanstack.ts
463
+ function routeEntriesFromTanStackRouteTree(routeTree) {
464
+ const out = [];
465
+ const seen = /* @__PURE__ */ new Set();
466
+ function visit(node, isRoot) {
467
+ if (!isTechnicalNode(node, isRoot)) {
468
+ const template = templateFromNode(node);
469
+ if (template !== null && !seen.has(template)) {
470
+ seen.add(template);
471
+ out.push({ template });
472
+ }
473
+ }
474
+ for (const child of childrenOf(node)) {
475
+ visit(child, false);
476
+ }
477
+ }
478
+ visit(routeTree, true);
479
+ return out;
480
+ }
481
+ function childrenOf(node) {
482
+ const kids = node.children;
483
+ if (kids === void 0 || kids === null) return [];
484
+ if (Array.isArray(kids)) return kids;
485
+ return Object.values(kids);
486
+ }
487
+ function isTechnicalNode(node, isRoot) {
488
+ if (isRoot) return true;
489
+ const id = node.id ?? "";
490
+ if (id === "__root__" || id === "root") return true;
491
+ const path = node.path ?? "";
492
+ if (path === "" && !node.fullPath) return true;
493
+ if (hasUnderscoreSegment(path) || hasUnderscoreSegment(id)) {
494
+ const full = node.fullPath ?? "";
495
+ if (full === "" || hasUnderscoreSegment(full)) return true;
496
+ }
497
+ return false;
498
+ }
499
+ function hasUnderscoreSegment(value) {
500
+ if (!value) return false;
501
+ return value.split("/").some((seg) => seg.startsWith("_") && seg.length > 1);
502
+ }
503
+ function templateFromNode(node) {
504
+ const raw = typeof node.fullPath === "string" && node.fullPath.length > 0 ? node.fullPath : typeof node.path === "string" && node.path.length > 0 ? node.path.startsWith("/") ? node.path : `/${node.path}` : null;
505
+ if (raw === null) return null;
506
+ if (hasUnderscoreSegment(raw)) return null;
507
+ return tanStackPathToUrlPattern(raw);
508
+ }
509
+ function tanStackPathToUrlPattern(path) {
510
+ if (path === "/" || path === "") return "/";
511
+ const segments = path.split("/");
512
+ const converted = segments.map((seg) => {
513
+ if (seg === "") return seg;
514
+ if (seg === "$") return "*";
515
+ if (seg.startsWith("$") && seg.endsWith("?")) {
516
+ return `:${seg.slice(1, -1)}`;
517
+ }
518
+ if (seg.startsWith("$")) return `:${seg.slice(1)}`;
519
+ return seg;
520
+ });
521
+ let result = converted.join("/");
522
+ result = result.replace(/\/{2,}/g, "/");
523
+ if (!result.startsWith("/")) result = `/${result}`;
524
+ if (result.length > 1 && result.endsWith("/")) {
525
+ result = result.slice(0, -1);
526
+ }
527
+ return result;
528
+ }
529
+ export {
530
+ WELL_KNOWN_CACHE_CONTROL,
531
+ WELL_KNOWN_CONTENT_TYPE,
532
+ WELL_KNOWN_MANIFEST_PATH,
533
+ createWellKnownHandler,
534
+ emitWellKnownManifest,
535
+ routeEntriesFromTanStackRouteTree,
536
+ serializeManifest,
537
+ tanStackPathToUrlPattern
538
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cavuno/board",
3
- "version": "1.41.0",
3
+ "version": "1.42.0",
4
4
  "description": "Typed isomorphic client for the Cavuno Board API",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -100,6 +100,36 @@
100
100
  "default": "./dist/paths.js"
101
101
  }
102
102
  },
103
+ "./go": {
104
+ "import": {
105
+ "types": "./dist/go.d.mts",
106
+ "default": "./dist/go.mjs"
107
+ },
108
+ "require": {
109
+ "types": "./dist/go.d.ts",
110
+ "default": "./dist/go.js"
111
+ }
112
+ },
113
+ "./route-contract": {
114
+ "import": {
115
+ "types": "./dist/route-contract.d.mts",
116
+ "default": "./dist/route-contract.mjs"
117
+ },
118
+ "require": {
119
+ "types": "./dist/route-contract.d.ts",
120
+ "default": "./dist/route-contract.js"
121
+ }
122
+ },
123
+ "./well-known": {
124
+ "import": {
125
+ "types": "./dist/well-known.d.mts",
126
+ "default": "./dist/well-known.mjs"
127
+ },
128
+ "require": {
129
+ "types": "./dist/well-known.d.ts",
130
+ "default": "./dist/well-known.js"
131
+ }
132
+ },
103
133
  "./server": {
104
134
  "import": {
105
135
  "types": "./dist/server.d.mts",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.41.0",
2
+ "version": "1.42.0",
3
3
  "skills": [
4
4
  {
5
5
  "name": "cavuno-board-account",