@burdenoff/microfe-atheletebridge 2026.716.2 → 2026.720.1
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.
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Page context gathering — captures the user's current
|
|
3
|
-
*
|
|
2
|
+
* Page context gathering — captures the user's current route context so the
|
|
3
|
+
* assistant can resolve "this / current / here" without asking for an id.
|
|
4
|
+
*
|
|
5
|
+
* Two rules govern this file:
|
|
6
|
+
*
|
|
7
|
+
* 1. The capture index is declared PER ROUTE (`idGroup`), never assumed to be
|
|
8
|
+
* `match[1]`. The athlete route (`/teams/:teamId/athletes/:memberId`) has two
|
|
9
|
+
* captures, and a shared `match[1]` read handed the assistant an
|
|
10
|
+
* `ATHLETEBRIDGE_ATHLETE` entityType paired with a TEAM id — a
|
|
11
|
+
* confidently-wrong context. Declaring the group per row makes that class of
|
|
12
|
+
* bug unrepresentable.
|
|
13
|
+
* 2. Only ids and types cross the wire. No athlete names, emails or metric
|
|
14
|
+
* values are ever forwarded, and only keys the agent actually accepts
|
|
15
|
+
* (`ALLOWED_CONTEXT_KEYS` in wspace/sandbox/ai-assistant/src/context-loader.ts)
|
|
16
|
+
* are emitted — `userAgent`/`timestamp` used to be sent and silently dropped.
|
|
4
17
|
*/
|
|
5
18
|
interface ConversationContextShape {
|
|
6
19
|
entityType?: string;
|
|
@@ -13,11 +26,7 @@ export interface PageContext {
|
|
|
13
26
|
currentPage: string;
|
|
14
27
|
entityType?: string;
|
|
15
28
|
entityId?: string;
|
|
16
|
-
|
|
17
|
-
version: string;
|
|
18
|
-
viewportSize: string;
|
|
19
|
-
userAgent: string;
|
|
20
|
-
timestamp: string;
|
|
29
|
+
activeTab?: string;
|
|
21
30
|
}
|
|
22
31
|
export declare function gatherPageContext(): PageContext;
|
|
23
32
|
export declare function resolveAthleteBridgeConversationContext(pathname: string, search: string): ConversationContextShape;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageContext.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/utils/pageContext.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pageContext.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/utils/pageContext.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,UAAU,wBAAwB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAG1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IAEpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuFD,wBAAgB,iBAAiB,IAAI,WAAW,CAe/C;AAED,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,wBAAwB,CAkC1B"}
|
|
@@ -1,48 +1,124 @@
|
|
|
1
1
|
//#region src/atheletebridge/utils/pageContext.ts
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
var e = new Set(["new", "edit"]), t = [
|
|
3
|
+
{
|
|
4
|
+
pattern: /^\/atheletebridge\/teams\/([^/]+)\/athletes\/([^/]+)$/,
|
|
5
|
+
entityType: "ATHLETEBRIDGE_ATHLETE",
|
|
6
|
+
idGroup: 2,
|
|
7
|
+
metadata: (e) => ({ teamId: e[1] })
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
pattern: /^\/atheletebridge\/teams\/([^/]+)\/edit$/,
|
|
11
|
+
entityType: "ATHLETEBRIDGE_TEAM",
|
|
12
|
+
idGroup: 1,
|
|
13
|
+
metadata: () => ({ mode: "edit" })
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
pattern: /^\/atheletebridge\/teams\/([^/]+)$/,
|
|
17
|
+
entityType: "ATHLETEBRIDGE_TEAM",
|
|
18
|
+
idGroup: 1
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
pattern: /^\/atheletebridge\/teams$/,
|
|
22
|
+
entityType: "ATHLETEBRIDGE_TEAMS",
|
|
23
|
+
idGroup: 0
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
pattern: /^\/atheletebridge\/fixtures\/([^/]+)$/,
|
|
27
|
+
entityType: "ATHLETEBRIDGE_FIXTURE",
|
|
28
|
+
idGroup: 1
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
pattern: /^\/atheletebridge\/fixtures$/,
|
|
32
|
+
entityType: "ATHLETEBRIDGE_FIXTURES",
|
|
33
|
+
idGroup: 0
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
pattern: /^\/atheletebridge\/programs\/([^/]+)\/edit$/,
|
|
37
|
+
entityType: "ATHLETEBRIDGE_PROGRAM",
|
|
38
|
+
idGroup: 1,
|
|
39
|
+
metadata: () => ({ mode: "edit" })
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
pattern: /^\/atheletebridge\/programs\/([^/]+)$/,
|
|
43
|
+
entityType: "ATHLETEBRIDGE_PROGRAM",
|
|
44
|
+
idGroup: 1
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
pattern: /^\/atheletebridge\/programs$/,
|
|
48
|
+
entityType: "ATHLETEBRIDGE_PROGRAMS",
|
|
49
|
+
idGroup: 0
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
pattern: /^\/atheletebridge\/sessions\/([^/]+)$/,
|
|
53
|
+
entityType: "ATHLETEBRIDGE_SESSION",
|
|
54
|
+
idGroup: 1
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
pattern: /^\/atheletebridge\/sessions$/,
|
|
58
|
+
entityType: "ATHLETEBRIDGE_SESSIONS",
|
|
59
|
+
idGroup: 0
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
pattern: /^\/atheletebridge\/standings$/,
|
|
63
|
+
entityType: "ATHLETEBRIDGE_STANDINGS",
|
|
64
|
+
idGroup: 0
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
pattern: /^\/atheletebridge\/performance$/,
|
|
68
|
+
entityType: "ATHLETEBRIDGE_PERFORMANCE",
|
|
69
|
+
idGroup: 0
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
pattern: /^\/atheletebridge\/analytics$/,
|
|
73
|
+
entityType: "ATHLETEBRIDGE_ANALYTICS",
|
|
74
|
+
idGroup: 0
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
pattern: /^\/atheletebridge\/tournaments$/,
|
|
78
|
+
entityType: "ATHLETEBRIDGE_TOURNAMENTS",
|
|
79
|
+
idGroup: 0
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
pattern: /^\/atheletebridge\/onboarding$/,
|
|
83
|
+
entityType: "ATHLETEBRIDGE_ONBOARDING",
|
|
84
|
+
idGroup: 0
|
|
85
|
+
}
|
|
86
|
+
];
|
|
87
|
+
function n() {
|
|
88
|
+
let e = window.location.pathname.split("/").filter(Boolean).slice(0, 3).join("/") || "home", t = r(window.location.pathname, window.location.search);
|
|
4
89
|
return {
|
|
5
|
-
currentUrl:
|
|
6
|
-
currentPage:
|
|
7
|
-
entityType:
|
|
8
|
-
entityId:
|
|
9
|
-
|
|
10
|
-
version: "2026.706.1",
|
|
11
|
-
viewportSize: `${window.innerWidth}x${window.innerHeight}`,
|
|
12
|
-
userAgent: navigator.userAgent,
|
|
13
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
90
|
+
currentUrl: window.location.href,
|
|
91
|
+
currentPage: e,
|
|
92
|
+
entityType: t.entityType,
|
|
93
|
+
entityId: t.entityId,
|
|
94
|
+
activeTab: t.activeTab
|
|
14
95
|
};
|
|
15
96
|
}
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
let i = t(n, e);
|
|
30
|
-
if (i) return {
|
|
31
|
-
entityType: r,
|
|
32
|
-
entityId: i[1],
|
|
33
|
-
metadata: { routePattern: n.source }
|
|
97
|
+
function r(n, r) {
|
|
98
|
+
let i = new URLSearchParams(r);
|
|
99
|
+
for (let r of t) {
|
|
100
|
+
let t = n.match(r.pattern);
|
|
101
|
+
if (!t) continue;
|
|
102
|
+
let i = r.idGroup > 0 ? t[r.idGroup] : void 0;
|
|
103
|
+
if (!(i !== void 0 && e.has(i))) return {
|
|
104
|
+
entityType: r.entityType,
|
|
105
|
+
...i ? { entityId: i } : {},
|
|
106
|
+
metadata: {
|
|
107
|
+
routePattern: r.pattern.source,
|
|
108
|
+
...r.metadata ? r.metadata(t) : {}
|
|
109
|
+
}
|
|
34
110
|
};
|
|
35
111
|
}
|
|
36
|
-
let
|
|
37
|
-
let
|
|
38
|
-
return
|
|
112
|
+
let a = i.get("tab") ?? (() => {
|
|
113
|
+
let e = n.split("/").filter(Boolean);
|
|
114
|
+
return e.length > 2 ? e[e.length - 1] : void 0;
|
|
39
115
|
})();
|
|
40
116
|
return {
|
|
41
|
-
activeTab:
|
|
42
|
-
metadata: { ...
|
|
117
|
+
activeTab: a ?? void 0,
|
|
118
|
+
metadata: { ...a ? { activeTab: a } : {} }
|
|
43
119
|
};
|
|
44
120
|
}
|
|
45
121
|
//#endregion
|
|
46
|
-
export {
|
|
122
|
+
export { n as gatherPageContext };
|
|
47
123
|
|
|
48
124
|
//# sourceMappingURL=pageContext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageContext.js","names":[],"sources":["../../../src/atheletebridge/utils/pageContext.ts"],"sourcesContent":["/**\n * Page context gathering — captures the user's current
|
|
1
|
+
{"version":3,"file":"pageContext.js","names":[],"sources":["../../../src/atheletebridge/utils/pageContext.ts"],"sourcesContent":["/**\n * Page context gathering — captures the user's current route context so the\n * assistant can resolve \"this / current / here\" without asking for an id.\n *\n * Two rules govern this file:\n *\n * 1. The capture index is declared PER ROUTE (`idGroup`), never assumed to be\n * `match[1]`. The athlete route (`/teams/:teamId/athletes/:memberId`) has two\n * captures, and a shared `match[1]` read handed the assistant an\n * `ATHLETEBRIDGE_ATHLETE` entityType paired with a TEAM id — a\n * confidently-wrong context. Declaring the group per row makes that class of\n * bug unrepresentable.\n * 2. Only ids and types cross the wire. No athlete names, emails or metric\n * values are ever forwarded, and only keys the agent actually accepts\n * (`ALLOWED_CONTEXT_KEYS` in wspace/sandbox/ai-assistant/src/context-loader.ts)\n * are emitted — `userAgent`/`timestamp` used to be sent and silently dropped.\n */\n\ninterface ConversationContextShape {\n entityType?: string;\n entityId?: string;\n activeTab?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface PageContext {\n // `currentUrl` (NOT `activeUrl`) — must match the agent's allowed-context-key\n // contract, otherwise the agent filters it out.\n currentUrl: string;\n currentPage: string;\n // The entity the user is currently looking at, resolved from the route.\n entityType?: string;\n entityId?: string;\n activeTab?: string;\n}\n\n/**\n * Route segments that are literals in the router, not entity ids. Without this\n * guard `/atheletebridge/teams/new` resolves to `entityId: 'new'`.\n */\nconst RESERVED_ID_SEGMENTS = new Set(['new', 'edit']);\n\ninterface RouteDescriptor {\n pattern: RegExp;\n entityType: string;\n /**\n * 1-based capture group holding the entity id, or 0 for index routes that\n * name a surface rather than a single record.\n */\n idGroup: number;\n /** Extra ids/flags derived from the match. Ids and types only — never names. */\n metadata?: (match: RegExpMatchArray) => Record<string, unknown>;\n}\n\n/**\n * Mirrors the routes registered in AthleteBridgeRoutes.tsx. Every shipped route\n * that names something the assistant can act on has a row here; anything absent\n * falls through to the generic `activeTab` branch and binds to nothing.\n */\nconst ROUTE_DESCRIPTORS: RouteDescriptor[] = [\n // Athlete detail is matched BEFORE team detail: its path is a strict\n // extension of the team path and the more specific pattern must win.\n {\n pattern: /^\\/atheletebridge\\/teams\\/([^/]+)\\/athletes\\/([^/]+)$/,\n entityType: 'ATHLETEBRIDGE_ATHLETE',\n idGroup: 2,\n metadata: (match) => ({ teamId: match[1] }),\n },\n {\n pattern: /^\\/atheletebridge\\/teams\\/([^/]+)\\/edit$/,\n entityType: 'ATHLETEBRIDGE_TEAM',\n idGroup: 1,\n metadata: () => ({ mode: 'edit' }),\n },\n {\n pattern: /^\\/atheletebridge\\/teams\\/([^/]+)$/,\n entityType: 'ATHLETEBRIDGE_TEAM',\n idGroup: 1,\n },\n { pattern: /^\\/atheletebridge\\/teams$/, entityType: 'ATHLETEBRIDGE_TEAMS', idGroup: 0 },\n {\n pattern: /^\\/atheletebridge\\/fixtures\\/([^/]+)$/,\n entityType: 'ATHLETEBRIDGE_FIXTURE',\n idGroup: 1,\n },\n { pattern: /^\\/atheletebridge\\/fixtures$/, entityType: 'ATHLETEBRIDGE_FIXTURES', idGroup: 0 },\n {\n pattern: /^\\/atheletebridge\\/programs\\/([^/]+)\\/edit$/,\n entityType: 'ATHLETEBRIDGE_PROGRAM',\n idGroup: 1,\n metadata: () => ({ mode: 'edit' }),\n },\n {\n pattern: /^\\/atheletebridge\\/programs\\/([^/]+)$/,\n entityType: 'ATHLETEBRIDGE_PROGRAM',\n idGroup: 1,\n },\n { pattern: /^\\/atheletebridge\\/programs$/, entityType: 'ATHLETEBRIDGE_PROGRAMS', idGroup: 0 },\n {\n pattern: /^\\/atheletebridge\\/sessions\\/([^/]+)$/,\n entityType: 'ATHLETEBRIDGE_SESSION',\n idGroup: 1,\n },\n { pattern: /^\\/atheletebridge\\/sessions$/, entityType: 'ATHLETEBRIDGE_SESSIONS', idGroup: 0 },\n // Index-only surfaces. AthleteBridgeRoutes.tsx registers no detail route for\n // these, so an id-capturing pattern here could never match anything real.\n { pattern: /^\\/atheletebridge\\/standings$/, entityType: 'ATHLETEBRIDGE_STANDINGS', idGroup: 0 },\n {\n pattern: /^\\/atheletebridge\\/performance$/,\n entityType: 'ATHLETEBRIDGE_PERFORMANCE',\n idGroup: 0,\n },\n { pattern: /^\\/atheletebridge\\/analytics$/, entityType: 'ATHLETEBRIDGE_ANALYTICS', idGroup: 0 },\n {\n pattern: /^\\/atheletebridge\\/tournaments$/,\n entityType: 'ATHLETEBRIDGE_TOURNAMENTS',\n idGroup: 0,\n },\n { pattern: /^\\/atheletebridge\\/onboarding$/, entityType: 'ATHLETEBRIDGE_ONBOARDING', idGroup: 0 },\n];\n\nexport function gatherPageContext(): PageContext {\n const pathSegments = window.location.pathname.split('/').filter(Boolean);\n const currentPage = pathSegments.slice(0, 3).join('/') || 'home';\n const entity = resolveAthleteBridgeConversationContext(\n window.location.pathname,\n window.location.search\n );\n\n return {\n currentUrl: window.location.href,\n currentPage,\n entityType: entity.entityType,\n entityId: entity.entityId,\n activeTab: entity.activeTab,\n };\n}\n\nexport function resolveAthleteBridgeConversationContext(\n pathname: string,\n search: string\n): ConversationContextShape {\n const params = new URLSearchParams(search);\n\n for (const descriptor of ROUTE_DESCRIPTORS) {\n const match = pathname.match(descriptor.pattern);\n if (!match) continue;\n\n const entityId = descriptor.idGroup > 0 ? match[descriptor.idGroup] : undefined;\n // `/teams/new` shape-matches `/teams/:id` — a router literal is not an id.\n if (entityId !== undefined && RESERVED_ID_SEGMENTS.has(entityId)) continue;\n\n return {\n entityType: descriptor.entityType,\n ...(entityId ? { entityId } : {}),\n metadata: {\n routePattern: descriptor.pattern.source,\n ...(descriptor.metadata ? descriptor.metadata(match) : {}),\n },\n };\n }\n\n const activeTab =\n params.get('tab') ??\n (() => {\n const segments = pathname.split('/').filter(Boolean);\n return segments.length > 2 ? segments[segments.length - 1] : undefined;\n })();\n\n return {\n activeTab: activeTab ?? undefined,\n metadata: {\n ...(activeTab ? { activeTab } : {}),\n },\n };\n}\n"],"mappings":";AAwCA,IAAM,IAAuB,IAAI,IAAI,CAAC,OAAO,OAAO,CAAC,EAmB/C,IAAuC;CAG3C;EACE,SAAS;EACT,YAAY;EACZ,SAAS;EACT,WAAW,OAAW,EAAE,QAAQ,EAAM,IAAI;EAC3C;CACD;EACE,SAAS;EACT,YAAY;EACZ,SAAS;EACT,iBAAiB,EAAE,MAAM,QAAQ;EAClC;CACD;EACE,SAAS;EACT,YAAY;EACZ,SAAS;EACV;CACD;EAAE,SAAS;EAA6B,YAAY;EAAuB,SAAS;EAAG;CACvF;EACE,SAAS;EACT,YAAY;EACZ,SAAS;EACV;CACD;EAAE,SAAS;EAAgC,YAAY;EAA0B,SAAS;EAAG;CAC7F;EACE,SAAS;EACT,YAAY;EACZ,SAAS;EACT,iBAAiB,EAAE,MAAM,QAAQ;EAClC;CACD;EACE,SAAS;EACT,YAAY;EACZ,SAAS;EACV;CACD;EAAE,SAAS;EAAgC,YAAY;EAA0B,SAAS;EAAG;CAC7F;EACE,SAAS;EACT,YAAY;EACZ,SAAS;EACV;CACD;EAAE,SAAS;EAAgC,YAAY;EAA0B,SAAS;EAAG;CAG7F;EAAE,SAAS;EAAiC,YAAY;EAA2B,SAAS;EAAG;CAC/F;EACE,SAAS;EACT,YAAY;EACZ,SAAS;EACV;CACD;EAAE,SAAS;EAAiC,YAAY;EAA2B,SAAS;EAAG;CAC/F;EACE,SAAS;EACT,YAAY;EACZ,SAAS;EACV;CACD;EAAE,SAAS;EAAkC,YAAY;EAA4B,SAAS;EAAG;CAClG;AAED,SAAgB,IAAiC;CAE/C,IAAM,IADe,OAAO,SAAS,SAAS,MAAM,IAAI,CAAC,OAAO,QAAQ,CACvC,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,IAAI,QACpD,IAAS,EACb,OAAO,SAAS,UAChB,OAAO,SAAS,OACjB;AAED,QAAO;EACL,YAAY,OAAO,SAAS;EAC5B;EACA,YAAY,EAAO;EACnB,UAAU,EAAO;EACjB,WAAW,EAAO;EACnB;;AAGH,SAAgB,EACd,GACA,GAC0B;CAC1B,IAAM,IAAS,IAAI,gBAAgB,EAAO;AAE1C,MAAK,IAAM,KAAc,GAAmB;EAC1C,IAAM,IAAQ,EAAS,MAAM,EAAW,QAAQ;AAChD,MAAI,CAAC,EAAO;EAEZ,IAAM,IAAW,EAAW,UAAU,IAAI,EAAM,EAAW,WAAW,KAAA;AAElE,cAAa,KAAA,KAAa,EAAqB,IAAI,EAAS,EAEhE,QAAO;GACL,YAAY,EAAW;GACvB,GAAI,IAAW,EAAE,aAAU,GAAG,EAAE;GAChC,UAAU;IACR,cAAc,EAAW,QAAQ;IACjC,GAAI,EAAW,WAAW,EAAW,SAAS,EAAM,GAAG,EAAE;IAC1D;GACF;;CAGH,IAAM,IACJ,EAAO,IAAI,MAAM,WACV;EACL,IAAM,IAAW,EAAS,MAAM,IAAI,CAAC,OAAO,QAAQ;AACpD,SAAO,EAAS,SAAS,IAAI,EAAS,EAAS,SAAS,KAAK,KAAA;KAC3D;AAEN,QAAO;EACL,WAAW,KAAa,KAAA;EACxB,UAAU,EACR,GAAI,IAAY,EAAE,cAAW,GAAG,EAAE,EACnC;EACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-atheletebridge",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.720.1",
|
|
4
4
|
"description": "Burdenoff AthleteBridge Microfrontend - Sports, coaching & training platform for teams, fixtures, programs, sessions and athlete performance",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -32,9 +32,10 @@
|
|
|
32
32
|
"codegen:all": "bun run schema:pull && bun run codegen",
|
|
33
33
|
"lint": "eslint .",
|
|
34
34
|
"lint:sanity": "if [ \"${CI:-}\" = \"true\" ]; then bun run lint; else bun run lint -- --cache --cache-location .eslintcache; fi",
|
|
35
|
-
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
35
|
+
"format": "prettier --write \"{src,tests}/**/*.{ts,tsx}\"",
|
|
36
36
|
"type:check": "tsc --noEmit",
|
|
37
|
-
"
|
|
37
|
+
"test": "bun test tests/",
|
|
38
|
+
"sanity": "bun run codegen && bun run lint:sanity && bun run format && bun run type:check && bun run test && bun run build && bun run build-storybook",
|
|
38
39
|
"storybook": "storybook dev -p 6006",
|
|
39
40
|
"build-storybook": "storybook build",
|
|
40
41
|
"test:storybook": "test-storybook",
|
|
@@ -43,7 +44,7 @@
|
|
|
43
44
|
"switch:local": "bun scripts/deps-mode.ts local",
|
|
44
45
|
"switch:check": "bun scripts/deps-mode.ts check",
|
|
45
46
|
"prepare": "lefthook install || true",
|
|
46
|
-
"format:check": "prettier --check \"src/**/*.{ts,tsx}\""
|
|
47
|
+
"format:check": "prettier --check \"{src,tests}/**/*.{ts,tsx}\""
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
|
49
50
|
"@apollo/client": "^4.0.11",
|