@contractspec/bundle.library 3.9.8 → 3.9.9
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/.turbo/turbo-build.log +222 -214
- package/CHANGELOG.md +52 -0
- package/dist/components/docs/DocsIndexPage.js +2 -2
- package/dist/components/docs/docsManifest.js +1 -1
- package/dist/components/docs/getting-started/DataViewTutorialPage.js +81 -6
- package/dist/components/docs/getting-started/index.js +94 -19
- package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.d.ts +6 -0
- package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.js +176 -0
- package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.d.ts +1 -0
- package/dist/components/docs/guides/GuideDataExchangeImportTemplatesPage.js +176 -0
- package/dist/components/docs/guides/GuidesIndexPage.js +2 -2
- package/dist/components/docs/guides/index.d.ts +1 -0
- package/dist/components/docs/guides/index.js +220 -46
- package/dist/components/docs/index.js +1003 -309
- package/dist/components/docs/libraries/LibrariesApplicationShellPage.content.d.ts +22 -5
- package/dist/components/docs/libraries/LibrariesApplicationShellPage.content.js +125 -37
- package/dist/components/docs/libraries/LibrariesApplicationShellPage.js +125 -37
- package/dist/components/docs/libraries/LibrariesDataViewsPage.js +120 -3
- package/dist/components/docs/libraries/LibrariesDesignSystemPage.js +101 -2
- package/dist/components/docs/libraries/LibrariesOverviewPage.js +1 -1
- package/dist/components/docs/libraries/LibrariesPersonalizationPage.js +58 -4
- package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.content.d.ts +10 -0
- package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.content.js +43 -0
- package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.d.ts +1 -0
- package/dist/components/docs/libraries/LibrariesTranslationRuntimePage.js +43 -0
- package/dist/components/docs/libraries/index.d.ts +1 -0
- package/dist/components/docs/libraries/index.js +496 -97
- package/dist/components/docs/specs/SpecsDataViewsPage.js +49 -3
- package/dist/components/docs/specs/index.js +60 -14
- package/dist/index.js +1014 -320
- package/dist/node/components/docs/DocsIndexPage.js +2 -2
- package/dist/node/components/docs/docsManifest.js +1 -1
- package/dist/node/components/docs/getting-started/DataViewTutorialPage.js +81 -6
- package/dist/node/components/docs/getting-started/index.js +94 -19
- package/dist/node/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.js +175 -0
- package/dist/node/components/docs/guides/GuideDataExchangeImportTemplatesPage.js +175 -0
- package/dist/node/components/docs/guides/GuidesIndexPage.js +2 -2
- package/dist/node/components/docs/guides/index.js +220 -46
- package/dist/node/components/docs/index.js +1003 -309
- package/dist/node/components/docs/libraries/LibrariesApplicationShellPage.content.js +125 -37
- package/dist/node/components/docs/libraries/LibrariesApplicationShellPage.js +125 -37
- package/dist/node/components/docs/libraries/LibrariesDataViewsPage.js +120 -3
- package/dist/node/components/docs/libraries/LibrariesDesignSystemPage.js +101 -2
- package/dist/node/components/docs/libraries/LibrariesOverviewPage.js +1 -1
- package/dist/node/components/docs/libraries/LibrariesPersonalizationPage.js +58 -4
- package/dist/node/components/docs/libraries/LibrariesTranslationRuntimePage.content.js +42 -0
- package/dist/node/components/docs/libraries/LibrariesTranslationRuntimePage.js +42 -0
- package/dist/node/components/docs/libraries/index.js +496 -97
- package/dist/node/components/docs/specs/SpecsDataViewsPage.js +49 -3
- package/dist/node/components/docs/specs/index.js +60 -14
- package/dist/node/index.js +1014 -320
- package/package.json +74 -26
- package/src/components/docs/docsManifest.test.ts +87 -0
- package/src/components/docs/docsManifest.ts +90 -3
- package/src/components/docs/generated/docs-index.notifications.json +7 -7
- package/src/components/docs/getting-started/DataViewTutorialPage.tsx +181 -50
- package/src/components/docs/guides/GuideDataExchangeImportTemplatesPage.content.ts +185 -0
- package/src/components/docs/guides/GuideDataExchangeImportTemplatesPage.tsx +186 -0
- package/src/components/docs/guides/GuidesIndexPage.tsx +49 -42
- package/src/components/docs/guides/index.ts +1 -0
- package/src/components/docs/libraries/LibrariesApplicationShellPage.content.ts +148 -35
- package/src/components/docs/libraries/LibrariesApplicationShellPage.tsx +38 -5
- package/src/components/docs/libraries/LibrariesDataViewsPage.tsx +267 -64
- package/src/components/docs/libraries/LibrariesDesignSystemPage.tsx +235 -0
- package/src/components/docs/libraries/LibrariesOverviewPage.tsx +8 -2
- package/src/components/docs/libraries/LibrariesPersonalizationPage.tsx +141 -31
- package/src/components/docs/libraries/LibrariesTranslationRuntimePage.content.ts +78 -0
- package/src/components/docs/libraries/LibrariesTranslationRuntimePage.tsx +137 -0
- package/src/components/docs/libraries/index.ts +1 -0
- package/src/components/docs/specs/SpecsDataViewsPage.tsx +239 -113
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
2
|
+
var W=Object.defineProperty;var Q=(g)=>g;function H(g,r){this[g]=Q.bind(null,r)}var Pe=(g,r)=>{for(var h in r)W(g,h,{get:r[h],enumerable:!0,configurable:!0,set:H.bind(r,h)})};var Le=(g,r)=>()=>(g&&(r=g(g=0)),r);import{CodeBlock as P,InstallCommand as J}from"@contractspec/lib.design-system";import G from"@contractspec/lib.ui-link";import{ChevronRight as _}from"lucide-react";import{jsx as i,jsxs as d}from"react/jsx-runtime";function Y(){return d("div",{className:"space-y-8",children:[d("div",{className:"space-y-2",children:[i("h1",{className:"font-bold text-4xl",children:"ContractSpec CLI"}),i("p",{className:"text-lg text-muted-foreground",children:"Command-line interface for creating, building, and validating contract specifications with AI-powered code generation."})]}),d("div",{className:"space-y-6",children:[d("div",{className:"space-y-3",children:[i("h2",{className:"font-bold text-2xl",children:"Installation"}),i(J,{package:"contractspec",dev:!0})]}),d("div",{className:"space-y-3",children:[i("h2",{className:"font-bold text-2xl",children:"Quick Start"}),i(P,{language:"bash",code:`# Initialize project
|
|
3
3
|
contractspec onboard
|
|
4
4
|
bunx contractspec init
|
|
5
5
|
|
|
@@ -10,13 +10,13 @@ contractspec create --type operation
|
|
|
10
10
|
contractspec generate
|
|
11
11
|
|
|
12
12
|
# Validate
|
|
13
|
-
contractspec validate`})]}),
|
|
13
|
+
contractspec validate`})]}),d("div",{className:"space-y-4",children:[i("h2",{className:"font-bold text-2xl",children:"Commands"}),i("div",{className:"grid gap-4",children:[{name:"onboard",description:"Primary OSS onboarding flow that recommends tracks, examples, and repo-local guides",usage:"contractspec onboard [track...] [--example <key>] [--dry-run] [--json]"},{name:"create",description:"Interactive wizard to create contract specifications",usage:"contractspec create [--type operation] [--ai]"},{name:"build",description:"Generate implementation code from contract specs using AI agents",usage:"contractspec build <spec-file> [--agent-mode claude-code]"},{name:"validate",description:"Validate contract specifications and implementations",usage:"contractspec validate <spec-file> [--check-implementation]"},{name:"list",description:"List all contract specifications in the project",usage:"contractspec list [--type operation] [--json]"},{name:"watch",description:"Watch specs and auto-regenerate on changes",usage:"contractspec watch [--build] [--validate]"},{name:"sync",description:"Sync contracts by building all discovered specs",usage:"contractspec sync [--dry-run]"},{name:"ci",description:"Run all validation checks for CI/CD pipelines",usage:"contractspec ci [--format sarif] [--output results.sarif]"},{name:"deps",description:"Analyze contract dependencies and relationships",usage:"contractspec deps [--circular] [--format dot]"},{name:"diff",description:"Compare contract specifications and show differences",usage:"contractspec diff <spec1> <spec2> [--breaking]"}].map((r)=>d("div",{className:"card-subtle space-y-2 p-4",children:[i("h3",{className:"font-bold font-mono text-violet-400",children:r.name}),i("p",{className:"text-muted-foreground text-sm",children:r.description}),i(P,{language:"bash",code:r.usage,showCopyButton:!1})]},r.name))})]}),d("div",{className:"space-y-3",children:[i("h2",{className:"font-bold text-2xl",children:"AI Agent Modes"}),i("p",{className:"text-muted-foreground",children:"The CLI supports multiple AI agent modes for different use cases:"}),d("div",{className:"grid gap-3 md:grid-cols-2",children:[d("div",{className:"card-subtle p-4",children:[i("h4",{className:"font-bold",children:"simple"}),i("p",{className:"text-muted-foreground text-sm",children:"Direct LLM API calls, fast and straightforward. Best for rapid prototyping."})]}),d("div",{className:"card-subtle p-4",children:[i("h4",{className:"font-bold",children:"claude-code"}),i("p",{className:"text-muted-foreground text-sm",children:"Extended thinking with Claude. Best for production-quality code."})]}),d("div",{className:"card-subtle p-4",children:[i("h4",{className:"font-bold",children:"openai-codex"}),i("p",{className:"text-muted-foreground text-sm",children:"GPT-4o/o1 models. Excellent for algorithms and optimization."})]}),d("div",{className:"card-subtle p-4",children:[i("h4",{className:"font-bold",children:"cursor"}),i("p",{className:"text-muted-foreground text-sm",children:"Leverages Cursor agentic capabilities. Requires Cursor environment."})]})]})]}),d("div",{className:"space-y-3",children:[i("h2",{className:"font-bold text-2xl",children:"CI/CD Integration"}),i("p",{className:"text-muted-foreground",children:"Run all validation checks in CI/CD with machine-readable output:"}),i(P,{language:"yaml",filename:".github/workflows/validate.yml",code:`- name: Validate Contracts
|
|
14
14
|
run: contractspec ci --format sarif --output results.sarif
|
|
15
15
|
|
|
16
16
|
- name: Upload SARIF
|
|
17
17
|
uses: github/codeql-action/upload-sarif@v3
|
|
18
18
|
with:
|
|
19
|
-
sarif_file: results.sarif`})]}),
|
|
19
|
+
sarif_file: results.sarif`})]}),d("div",{className:"card-subtle space-y-4 p-6",children:[i("h3",{className:"font-bold",children:"Configuration"}),d("p",{className:"text-muted-foreground text-sm",children:["Create a ",i("code",{children:".contractsrc.json"})," file in your project root:"]}),i(P,{language:"json",filename:".contractsrc.json",code:`{
|
|
20
20
|
"aiProvider": "claude",
|
|
21
21
|
"agentMode": "claude-code",
|
|
22
22
|
"outputDir": "./src",
|
|
@@ -24,7 +24,7 @@ contractspec validate`})]}),s("div",{className:"space-y-4",children:[a("h2",{cla
|
|
|
24
24
|
"operations": "interactions/commands|queries",
|
|
25
25
|
"events": "events"
|
|
26
26
|
}
|
|
27
|
-
}`})]})]}),
|
|
27
|
+
}`})]})]}),d("div",{className:"flex items-center gap-4 pt-4",children:[d(G,{href:"/docs/getting-started/tools/vscode",className:"btn-primary",children:["Next: VS Code Extension ",i(_,{size:16})]}),i(G,{href:"/docs/getting-started/tools",className:"btn-ghost",children:"Back to Tools"})]})]})}import L from"@contractspec/lib.ui-link";import{ChevronRight as $}from"lucide-react";import{jsx as o,jsxs as p}from"react/jsx-runtime";function K(){return p("div",{className:"space-y-8",children:[p("div",{className:"space-y-2",children:[o("h1",{className:"font-bold text-4xl",children:"Compatibility"}),o("p",{className:"text-lg text-muted-foreground",children:"Supported runtimes, frameworks, and agent modes for ContractSpec."})]}),p("div",{className:"space-y-6",children:[p("div",{className:"card-subtle space-y-3 p-6",children:[o("h2",{className:"font-bold text-2xl",children:"Runtimes"}),p("ul",{className:"space-y-2 text-muted-foreground",children:[o("li",{children:"Node.js 20+"}),o("li",{children:"Bun 1.0+"})]})]}),p("div",{className:"card-subtle space-y-3 p-6",children:[o("h2",{className:"font-bold text-2xl",children:"Frameworks"}),p("ul",{className:"space-y-2 text-muted-foreground",children:[o("li",{children:"Next.js 14+ (App Router preferred)"}),o("li",{children:"Bun + Elysia or compatible HTTP servers"})]})]}),p("div",{className:"card-subtle space-y-3 p-6",children:[o("h2",{className:"font-bold text-2xl",children:"Package managers"}),p("ul",{className:"space-y-2 text-muted-foreground",children:[o("li",{children:"bun (recommended)"}),o("li",{children:"npm"}),o("li",{children:"pnpm"})]})]}),p("div",{className:"card-subtle space-y-3 p-6",children:[o("h2",{className:"font-bold text-2xl",children:"AI agent modes"}),p("ul",{className:"space-y-2 text-muted-foreground",children:[o("li",{children:"claude-code"}),o("li",{children:"openai-codex"}),o("li",{children:"cursor"}),o("li",{children:"opencode"}),o("li",{children:"simple (direct LLM)"})]})]}),p("div",{className:"card-subtle space-y-3 p-6",children:[o("h2",{className:"font-bold text-2xl",children:"Datastores"}),o("p",{className:"text-muted-foreground",children:"ContractSpec ships with Prisma-friendly defaults and can integrate with custom adapters for other databases."}),p("ul",{className:"space-y-2 text-muted-foreground",children:[o("li",{children:"PostgreSQL via Prisma"}),o("li",{children:"Custom adapters for other SQL/NoSQL stores"})]})]}),p("div",{className:"card-subtle space-y-3 p-6",children:[o("h2",{className:"font-bold text-2xl",children:"Cross-platform UI architecture"}),p("p",{className:"text-muted-foreground",children:["Need the React and React Native component compatibility story? Read"," ",o(L,{href:"/docs/libraries/cross-platform-ui",className:"text-[color:var(--rust)] underline underline-offset-4",children:"Cross-platform UI"})," ","for the runtime and UI-layer split."]})]})]}),p("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[o(L,{href:"/docs/getting-started/start-here",className:"btn-ghost",children:"Start here"}),o(L,{href:"/docs/getting-started/troubleshooting",className:"btn-ghost",children:"Troubleshooting"}),p(L,{href:"/docs/getting-started/installation",className:"btn-primary",children:["Next: Installation ",o($,{size:16})]})]})]})}import{CodeBlock as R}from"@contractspec/lib.design-system";import{HStack as X,VStack as S}from"@contractspec/lib.design-system/layout";import{List as Z,ListItem as w}from"@contractspec/lib.design-system/list";import{H1 as x,H2 as E,H3 as j,P as k,Text as v}from"@contractspec/lib.design-system/typography";import O from"@contractspec/lib.ui-link";import{ChevronRight as ee}from"lucide-react";import{jsx as t,jsxs as y}from"react/jsx-runtime";var te=`import { defineDataView } from '@contractspec/lib.contracts-spec/data-views';
|
|
28
28
|
import { ListTransactions } from './list-transactions';
|
|
29
29
|
|
|
30
30
|
export const TransactionHistory = defineDataView({
|
|
@@ -86,8 +86,41 @@ export const TransactionHistory = defineDataView({
|
|
|
86
86
|
dataPath: 'processingMinutes',
|
|
87
87
|
format: { type: 'duration', unit: 'minute', display: 'digital' },
|
|
88
88
|
},
|
|
89
|
-
{
|
|
89
|
+
{
|
|
90
|
+
key: 'notes',
|
|
91
|
+
label: 'Notes',
|
|
92
|
+
dataPath: 'notes',
|
|
93
|
+
visibility: { minDataDepth: 'detailed' },
|
|
94
|
+
},
|
|
90
95
|
],
|
|
96
|
+
collection: {
|
|
97
|
+
viewModes: {
|
|
98
|
+
defaultMode: 'table',
|
|
99
|
+
allowedModes: ['list', 'grid', 'table'],
|
|
100
|
+
},
|
|
101
|
+
toolbar: {
|
|
102
|
+
search: true,
|
|
103
|
+
viewMode: true,
|
|
104
|
+
filters: true,
|
|
105
|
+
density: true,
|
|
106
|
+
dataDepth: true,
|
|
107
|
+
},
|
|
108
|
+
pagination: {
|
|
109
|
+
pageSize: 25,
|
|
110
|
+
pageSizeOptions: [10, 25, 50],
|
|
111
|
+
},
|
|
112
|
+
density: 'comfortable',
|
|
113
|
+
dataDepth: 'standard',
|
|
114
|
+
personalization: {
|
|
115
|
+
enabled: true,
|
|
116
|
+
persist: {
|
|
117
|
+
viewMode: true,
|
|
118
|
+
density: true,
|
|
119
|
+
dataDepth: true,
|
|
120
|
+
pageSize: true,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
91
124
|
filters: [
|
|
92
125
|
{ key: 'status', label: 'Status', field: 'status', type: 'enum' },
|
|
93
126
|
{
|
|
@@ -106,7 +139,7 @@ export const TransactionHistory = defineDataView({
|
|
|
106
139
|
},
|
|
107
140
|
],
|
|
108
141
|
},
|
|
109
|
-
});`;function
|
|
142
|
+
});`;function ae(){return y(S,{className:"space-y-8",children:[y(S,{className:"space-y-4",children:[t(x,{className:"font-bold text-4xl",children:"Display Data with DataViews"}),t(k,{className:"text-lg text-muted-foreground",children:"Define a filterable, sortable transaction history view that works across web and mobile without duplicating UI code."})]}),y(S,{className:"space-y-4",children:[t(E,{className:"font-bold text-2xl",children:"1. Define the underlying query"}),t(k,{className:"text-muted-foreground",children:"First, create a query operation to fetch the data:"}),t(R,{language:"typescript",filename:"lib/specs/billing/list-transactions.ts",code:`import { defineQuery } from '@contractspec/lib.contracts-spec';
|
|
110
143
|
|
|
111
144
|
export const ListTransactions = defineQuery({
|
|
112
145
|
meta: {
|
|
@@ -119,7 +152,7 @@ export const ListTransactions = defineQuery({
|
|
|
119
152
|
output: /* array of transactions */,
|
|
120
153
|
},
|
|
121
154
|
policy: { auth: 'user' },
|
|
122
|
-
});`})]}),
|
|
155
|
+
});`})]}),y(S,{className:"space-y-4",children:[t(E,{className:"font-bold text-2xl",children:"2. Define the DataView spec"}),t(k,{className:"text-muted-foreground",children:"Wrap your query with presentation metadata:"}),t(R,{language:"typescript",filename:"lib/specs/billing/transaction-history.data-view.ts",code:te}),y(k,{className:"text-muted-foreground text-sm",children:["The live version of this pattern is available in the canonical"," ",t(O,{href:"/docs/examples/data-grid-showcase",className:"text-[color:var(--rust)] underline underline-offset-4",children:t(v,{children:"Data Grid Showcase"})}),"."]})]}),y(S,{className:"space-y-4",children:[t(E,{className:"font-bold text-2xl",children:"3. Render on the frontend"}),t(k,{className:"text-muted-foreground",children:"Use the runtime renderer in your React or React Native app:"}),t(R,{language:"tsx",filename:"app/dashboard/transactions/page.tsx",code:`'use client';
|
|
123
156
|
|
|
124
157
|
import { DataViewRenderer } from '@contractspec/lib.design-system';
|
|
125
158
|
import { TransactionHistory } from '@/lib/specs/billing/transaction-history.data-view';
|
|
@@ -136,15 +169,57 @@ export function TransactionsPage() {
|
|
|
136
169
|
<h1 className="text-3xl font-bold mb-6">Payment History</h1>
|
|
137
170
|
<DataViewRenderer
|
|
138
171
|
spec={TransactionHistory}
|
|
139
|
-
|
|
172
|
+
items={data?.items ?? []}
|
|
140
173
|
loading={isLoading}
|
|
174
|
+
defaultViewMode="table"
|
|
175
|
+
defaultDensity="comfortable"
|
|
176
|
+
defaultDataDepth="standard"
|
|
141
177
|
onFilterChange={(filters) => {
|
|
142
178
|
// refetch with new filters
|
|
143
179
|
}}
|
|
144
180
|
/>
|
|
145
181
|
</div>
|
|
146
182
|
);
|
|
147
|
-
}`})]}),
|
|
183
|
+
}`})]}),y(S,{className:"space-y-4",children:[t(E,{className:"font-bold text-2xl",children:"4. Add personalization"}),t(k,{className:"text-muted-foreground",children:"When the app has a user profile or behavior insights, resolve DataView preferences before rendering. The renderer receives plain props; personalization stays in the app/runtime boundary."}),t(R,{language:"tsx",filename:"app/dashboard/transactions/PersonalizedTransactions.tsx",code:`'use client';
|
|
184
|
+
|
|
185
|
+
import { DataViewRenderer } from '@contractspec/lib.design-system';
|
|
186
|
+
import { resolveDataViewPreferences } from '@contractspec/lib.personalization/data-view-preferences';
|
|
187
|
+
import { createBehaviorTracker } from '@contractspec/lib.personalization';
|
|
188
|
+
|
|
189
|
+
const tracker = createBehaviorTracker({
|
|
190
|
+
store,
|
|
191
|
+
context: { tenantId: tenant.id, userId: user.id },
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const resolved = resolveDataViewPreferences({
|
|
195
|
+
spec: TransactionHistory,
|
|
196
|
+
preferences: profile.canonical,
|
|
197
|
+
insights,
|
|
198
|
+
record: savedTransactionViewPreference,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
<DataViewRenderer
|
|
202
|
+
spec={TransactionHistory}
|
|
203
|
+
items={transactions}
|
|
204
|
+
defaultViewMode={resolved.viewMode}
|
|
205
|
+
defaultDensity={resolved.density}
|
|
206
|
+
defaultDataDepth={resolved.dataDepth}
|
|
207
|
+
pagination={{ page, pageSize: resolved.pageSize ?? 25, total }}
|
|
208
|
+
onViewModeChange={(viewMode) =>
|
|
209
|
+
tracker.trackDataViewInteraction({
|
|
210
|
+
dataViewKey: TransactionHistory.meta.key,
|
|
211
|
+
action: 'view_mode_changed',
|
|
212
|
+
viewMode,
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
onDataDepthChange={(dataDepth) =>
|
|
216
|
+
tracker.trackDataViewInteraction({
|
|
217
|
+
dataViewKey: TransactionHistory.meta.key,
|
|
218
|
+
action: 'data_depth_changed',
|
|
219
|
+
dataDepth,
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
/>;`})]}),y(S,{className:"card-subtle space-y-4 p-6",children:[t(j,{className:"font-bold",children:"Why DataViews?"}),y(Z,{className:"space-y-2 text-muted-foreground text-sm",children:[t(w,{children:t(v,{children:"Same spec renders on web (React) and mobile (React Native)"})}),t(w,{children:t(v,{children:"Filters, sorting, and pagination handled automatically"})}),t(w,{children:t(v,{children:"Column visibility, pinning, resizing, and row expansion stay contract-driven"})}),t(w,{children:t(v,{children:"List, grid, and table modes can share one collection config with toolbar and pagination defaults"})}),t(w,{children:t(v,{children:"Data depth lets summary screens hide detailed fields without forking the spec"})}),t(w,{children:t(v,{children:"Typed format rules for numbers, percent values, currency, dates, times, datetimes, and durations applied consistently"})}),t(w,{children:t(v,{children:"Personalization helpers can seed preferred view mode, density, data depth, and page size from user preferences or behavior insights"})}),t(w,{children:t(v,{children:"Export to CSV/PDF using the same spec"})}),t(w,{children:t(v,{children:"A/B test different layouts without touching the backend"})})]})]}),y(X,{className:"items-center gap-4 pt-4",children:[y(O,{href:"/docs/libraries/data-views",className:"btn-primary",children:[t(v,{children:"DataView API Reference"})," ",t(ee,{size:16})]}),t(O,{href:"/docs/specs/workflows",className:"btn-ghost",children:t(v,{children:"Next: Workflows"})})]})]})}import{CodeBlock as ie,InstallCommand as oe}from"@contractspec/lib.design-system";import B from"@contractspec/lib.ui-link";import{ChevronRight as q,Code2 as ne,Cpu as re,Layers as ce,Terminal as le}from"lucide-react";import{jsx as s,jsxs as N}from"react/jsx-runtime";function Ke(){return N("div",{className:"space-y-8",children:[N("div",{className:"space-y-2",children:[s("h1",{className:"font-bold text-4xl",children:"Developer Tools"}),s("p",{className:"text-lg text-muted-foreground",children:"Use the OSS toolchain to define contracts, validate changes, inspect generated surfaces, and adopt the system incrementally across different environments."})]}),s("div",{className:"grid gap-6 md:grid-cols-2",children:[{name:"CLI",href:"/docs/getting-started/tools/cli",description:"Command-line interface for spec creation, building, validation, and CI/CD integration.",icon:le,status:"available",highlights:["AI-powered code generation","Multiple agent modes","SARIF/JSON output"]},{name:"VS Code Extension",href:"/docs/getting-started/tools/vscode",description:"Real-time validation, scaffolding, and navigation directly in your editor.",icon:ne,status:"available",highlights:["Specs Explorer sidebar","Watch mode","Interactive walkthroughs"]},{name:"ContractSpec Studio",href:"https://www.contractspec.studio",description:"The operating layer on top of OSS ContractSpec for teams that want evidence-backed decisions, workflow automation, and managed delivery loops.",icon:ce,status:"available",highlights:["Evidence-to-decision loop","Compiled spec diffs and task packs","Exports to Linear, Jira, Notion, and GitHub"]},{name:"JetBrains Plugin",href:"#",description:"Full ContractSpec support for IntelliJ, WebStorm, and other JetBrains IDEs.",icon:re,status:"coming-soon",highlights:["Code navigation","Inline validation","Refactoring support"]}].map((r)=>{let h=r.icon,I=r.status==="coming-soon";return N("div",{className:`card-subtle relative space-y-4 p-6 ${I?"opacity-75":""}`,children:[I&&s("span",{className:"absolute -top-2 right-4 rounded-full bg-violet-500/20 px-2 py-0.5 font-medium text-violet-400 text-xs",children:"Coming Soon"}),N("div",{className:"flex items-center gap-3",children:[s("div",{className:"flex h-10 w-10 items-center justify-center rounded-lg bg-violet-500/10",children:s(h,{className:"h-5 w-5 text-violet-400"})}),s("h3",{className:"font-bold text-lg",children:r.name})]}),s("p",{className:"text-muted-foreground text-sm",children:r.description}),s("ul",{className:"space-y-1",children:r.highlights.map((M)=>N("li",{className:"flex items-center gap-2 text-muted-foreground text-sm",children:[s("span",{className:"text-violet-400",children:"-"}),M]},M))}),!I&&N(B,{href:r.href,className:"btn-ghost inline-flex items-center gap-1 text-sm",children:["Learn more ",s(q,{size:14})]})]},r.name)})}),N("div",{className:"card-subtle space-y-4 p-6",children:[s("h3",{className:"font-bold",children:"Quick Install"}),N("div",{className:"space-y-3",children:[N("div",{children:[s("p",{className:"mb-2 font-medium text-muted-foreground text-xs",children:"CLI"}),s(oe,{package:"contractspec",dev:!0})]}),N("div",{children:[s("p",{className:"mb-2 font-medium text-muted-foreground text-xs",children:"VS Code Extension"}),s(ie,{language:"bash",code:"code --install-extension lssm.vscode-contractspec"})]})]})]}),N("div",{className:"flex items-center gap-4 pt-4",children:[N(B,{href:"/docs/getting-started/tools/cli",className:"btn-primary",children:["Get Started with CLI ",s(q,{size:16})]}),s(B,{href:"/docs/getting-started/tools/vscode",className:"btn-ghost",children:"VS Code Extension"})]})]})}import{CodeBlock as A}from"@contractspec/lib.design-system";import de from"@contractspec/lib.ui-link";import{ChevronRight as se}from"lucide-react";import{jsx as n,jsxs as f}from"react/jsx-runtime";function pe(){return f("div",{className:"space-y-8",children:[f("div",{className:"space-y-2",children:[n("h1",{className:"font-bold text-4xl",children:"Your First Operation"}),n("p",{className:"text-lg text-muted-foreground",children:"Build a payment capture operation with policy enforcement in under 10 minutes."})]}),f("div",{className:"space-y-6",children:[f("div",{className:"space-y-3",children:[n("h2",{className:"font-bold text-2xl",children:"What you'll build"}),n("p",{className:"text-muted-foreground",children:"A real-world payment processing operation that validates input, enforces business rules, integrates with Stripe, and audits every transaction. This is production-ready code, not a toy example."})]}),f("div",{className:"space-y-3",children:[n("h2",{className:"font-bold text-2xl",children:"1. Define the operation spec"}),f("p",{className:"text-muted-foreground",children:["Create ",n("code",{children:"lib/specs/billing/capture-payment.ts"}),":"]}),n(A,{language:"typescript",filename:"lib/specs/billing/capture-payment.ts",code:`import { defineCommand } from '@contractspec/lib.contracts-spec';
|
|
148
223
|
import { SchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
|
|
149
224
|
|
|
150
225
|
const CapturePaymentInput = new SchemaModel({
|
|
@@ -187,7 +262,7 @@ export const CapturePayment = defineCommand({
|
|
|
187
262
|
{ resource: 'invoice', action: 'pay', condition: 'owner' },
|
|
188
263
|
],
|
|
189
264
|
},
|
|
190
|
-
});`})]}),f("div",{className:"space-y-3",children:[
|
|
265
|
+
});`})]}),f("div",{className:"space-y-3",children:[n("h2",{className:"font-bold text-2xl",children:"2. Implement the handler"}),f("p",{className:"text-muted-foreground",children:["Create ",n("code",{children:"lib/handlers/billing/capture-payment.ts"}),":"]}),n(A,{language:"typescript",filename:"lib/handlers/billing/capture-payment.ts",code:`import { CapturePayment } from '@/lib/specs/billing/capture-payment';
|
|
191
266
|
import { stripe } from '@/lib/integrations/stripe';
|
|
192
267
|
import { db } from '@/lib/db';
|
|
193
268
|
|
|
@@ -224,12 +299,12 @@ export async function handleCapturePayment(input, ctx) {
|
|
|
224
299
|
status: paymentIntent.status,
|
|
225
300
|
receiptUrl: paymentIntent.charges.data[0]?.receipt_url,
|
|
226
301
|
};
|
|
227
|
-
}`})]}),f("div",{className:"space-y-3",children:[
|
|
302
|
+
}`})]}),f("div",{className:"space-y-3",children:[n("h2",{className:"font-bold text-2xl",children:"3. Register and serve"}),f("p",{className:"text-muted-foreground",children:["Wire it up in ",n("code",{children:"lib/registry.ts"})," and"," ",n("code",{children:"app/api/ops/[...route]/route.ts"}),":"]}),n(A,{language:"typescript",filename:"lib/registry.ts",code:`import { OperationSpecRegistry, installOp } from '@contractspec/lib.contracts-spec';
|
|
228
303
|
import { CapturePayment } from './specs/billing/capture-payment';
|
|
229
304
|
import { handleCapturePayment } from './handlers/billing/capture-payment';
|
|
230
305
|
|
|
231
306
|
export const registry = new OperationSpecRegistry();
|
|
232
|
-
installOp(registry, CapturePayment, handleCapturePayment);`}),
|
|
307
|
+
installOp(registry, CapturePayment, handleCapturePayment);`}),n(A,{language:"typescript",filename:"app/api/ops/[...route]/route.ts",code:`import { makeNextAppHandler } from '@contractspec/lib.contracts-runtime-server-rest/rest-next-app';
|
|
233
308
|
import { registry } from '@/lib/registry';
|
|
234
309
|
import { auth } from '@/lib/auth';
|
|
235
310
|
|
|
@@ -238,16 +313,16 @@ const handler = makeNextAppHandler(registry, async (req) => {
|
|
|
238
313
|
return { actor: 'user', userId: session.userId, tenantId: session.tenantId };
|
|
239
314
|
});
|
|
240
315
|
|
|
241
|
-
export { handler as GET, handler as POST };`})]}),f("div",{className:"card-subtle space-y-4 p-6",children:[
|
|
242
|
-
# Follow the interactive prompts to configure your project`})]}),
|
|
316
|
+
export { handler as GET, handler as POST };`})]}),f("div",{className:"card-subtle space-y-4 p-6",children:[n("h3",{className:"font-bold",children:"What you just built:"}),f("ul",{className:"space-y-2 text-muted-foreground text-sm",children:[f("li",{children:["Type-safe API endpoint at"," ",n("code",{children:"/api/ops/billing.capturePayment"})]}),n("li",{children:"Automatic input validation (amount must be positive, IDs required)"}),n("li",{children:"Policy enforcement\u2014only invoice owner can pay"}),n("li",{children:"Stripe integration with error handling"}),n("li",{children:"Database transaction with audit trail"}),n("li",{children:"Same spec works with GraphQL, MCP, or webhooks"})]})]}),n("div",{className:"flex items-center gap-4 pt-4",children:f(de,{href:"/docs/getting-started/dataviews",className:"btn-primary",children:["Next: Display Data with DataViews ",n(se,{size:16})]})})]})]})}import{CodeBlock as F,InstallCommand as D}from"@contractspec/lib.design-system";import me from"@contractspec/lib.ui-link";import{ChevronRight as ue}from"lucide-react";import{jsx as c,jsxs as b}from"react/jsx-runtime";function fe(){return b("div",{className:"space-y-8",children:[b("div",{className:"space-y-2",children:[c("h1",{className:"font-bold text-4xl",children:"Installation"}),c("p",{className:"text-lg text-muted-foreground",children:"Add ContractSpec to your existing Next.js or Bun project, or start fresh."})]}),b("div",{className:"space-y-6",children:[b("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"Prerequisites"}),b("ul",{className:"space-y-2 text-muted-foreground",children:[c("li",{children:"Node.js 20+ (or Bun 1.0+)"}),c("li",{children:"Existing Next.js app or Bun HTTP server"}),c("li",{children:"PostgreSQL database (for persistence)"})]})]}),b("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"Install Core Libraries"}),c("p",{className:"text-muted-foreground",children:"Add the contracts runtime and your choice of adapter:"}),c(D,{package:["@contractspec/lib.contracts-spec","@contractspec/lib.schema"]})]}),b("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"For Next.js projects"}),c(D,{package:"@contractspec/lib.contracts-spec"})]}),b("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"For database models"}),c(D,{package:["@contractspec/app.cli-database","prisma","@prisma/client"]})]}),b("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"Set up your project"}),c("p",{className:"text-muted-foreground",children:"Initialize a new ContractSpec project structure:"}),c(F,{language:"bash",filename:"installation-init",code:`bunx contractspec init
|
|
317
|
+
# Follow the interactive prompts to configure your project`})]}),b("div",{className:"space-y-3",children:[c("h2",{className:"font-bold text-2xl",children:"Initialize the database"}),c("p",{className:"text-muted-foreground",children:"If using Prisma, set up your schema and generate the client:"}),c(F,{language:"bash",filename:"installation-prisma",code:`bunx prisma init
|
|
243
318
|
# Edit prisma/schema.prisma with your models
|
|
244
319
|
bunx prisma generate
|
|
245
|
-
bunx prisma migrate dev --name init`})]}),c("div",{className:"flex items-center gap-4 pt-4",children:
|
|
320
|
+
bunx prisma migrate dev --name init`})]}),c("div",{className:"flex items-center gap-4 pt-4",children:b(me,{href:"/docs/getting-started/hello-world",className:"btn-primary",children:["Next: First Operation ",c(ue,{size:16})]})})]})]})}import{CodeBlock as z,InstallCommand as ge}from"@contractspec/lib.design-system";import T from"@contractspec/lib.ui-link";import{ChevronRight as he}from"lucide-react";import{jsx as u,jsxs as C}from"react/jsx-runtime";function ve(){return C("div",{className:"space-y-8",children:[C("div",{className:"space-y-2",children:[u("h1",{className:"font-bold text-4xl",children:"Start here"}),u("p",{className:"text-lg text-muted-foreground",children:"A fast onboarding path from install to your first generated contract."})]}),C("div",{className:"space-y-6",children:[C("div",{className:"space-y-3",children:[u("h2",{className:"font-bold text-2xl",children:"Install the CLI"}),u(ge,{package:"contractspec",dev:!0})]}),C("div",{className:"space-y-3",children:[u("h2",{className:"font-bold text-2xl",children:"Generate repo-local guidance"}),u(z,{language:"bash",filename:"start-here-onboard",code:`contractspec onboard
|
|
246
321
|
# optional focused track
|
|
247
|
-
contractspec onboard knowledge --example knowledge-canon`})]}),
|
|
248
|
-
contractspec validate`})]})]}),
|
|
322
|
+
contractspec onboard knowledge --example knowledge-canon`})]}),C("div",{className:"space-y-3",children:[u("h2",{className:"font-bold text-2xl",children:"Initialize your project"}),u(z,{language:"bash",filename:"start-here-init",code:"bunx contractspec init"})]}),C("div",{className:"space-y-3",children:[u("h2",{className:"font-bold text-2xl",children:"Author your first contract"}),u(z,{language:"bash",filename:"start-here-create",code:"contractspec create --type operation"})]}),C("div",{className:"space-y-3",children:[u("h2",{className:"font-bold text-2xl",children:"Generate implementation"}),u(z,{language:"bash",filename:"start-here-build",code:`contractspec generate
|
|
323
|
+
contractspec validate`})]})]}),C("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[C(T,{href:"/docs/getting-started/hello-world",className:"btn-primary",children:["Next: Hello World ",u(he,{size:16})]}),u(T,{href:"/docs/getting-started/troubleshooting",className:"btn-ghost",children:"Troubleshooting"}),u(T,{href:"/docs/getting-started/compatibility",className:"btn-ghost",children:"Compatibility"})]})]})}import{CodeBlock as Ne}from"@contractspec/lib.design-system";import V from"@contractspec/lib.ui-link";import{ChevronRight as ye}from"lucide-react";import{jsx as l,jsxs as m}from"react/jsx-runtime";function be(){return m("div",{className:"space-y-8",children:[m("div",{className:"space-y-2",children:[l("h1",{className:"font-bold text-4xl",children:"Troubleshooting"}),l("p",{className:"text-lg text-muted-foreground",children:"Common issues and fixes when installing or generating with ContractSpec."})]}),m("div",{className:"space-y-6",children:[m("div",{className:"card-subtle space-y-3 p-6",children:[l("h2",{className:"font-bold text-2xl",children:"Command not found"}),m("ul",{className:"space-y-2 text-muted-foreground",children:[l("li",{children:"Reinstall the CLI and ensure it is in your PATH."}),l("li",{children:"Confirm Node.js 20+ or Bun 1.0+ is installed."})]})]}),m("div",{className:"card-subtle space-y-3 p-6",children:[l("h2",{className:"font-bold text-2xl",children:"Specs not discovered"}),m("ul",{className:"space-y-2 text-muted-foreground",children:[m("li",{children:["Run ",l("code",{children:"contractspec list"})," to see discovered specs."]}),l("li",{children:"Verify your spec path conventions in .contractsrc.json."})]})]}),m("div",{className:"card-subtle space-y-3 p-6",children:[l("h2",{className:"font-bold text-2xl",children:"Build or validate fails"}),m("ul",{className:"space-y-2 text-muted-foreground",children:[m("li",{children:["Run ",l("code",{children:"contractspec validate"})," to surface schema errors."]}),l("li",{children:"Check that generated files were not manually edited."})]})]}),m("div",{className:"space-y-3",children:[l("h2",{className:"font-bold text-2xl",children:"Diagnostics"}),l(Ne,{language:"bash",filename:"troubleshooting-diagnostics",code:`contractspec --version
|
|
249
324
|
contractspec list
|
|
250
|
-
contractspec validate src/contracts/mySpec.ts`})]}),m("div",{className:"card-subtle space-y-3 p-6",children:[l("h2",{className:"font-bold text-2xl",children:"Still blocked?"}),m("ul",{className:"space-y-2 text-muted-foreground",children:[l("li",{children:"Confirm compatibility requirements for runtime and framework."}),l("li",{children:"Re-run builds on a clean branch to isolate changes."}),l("li",{children:"Use a new spec and minimal adapter to validate setup."})]})]})]}),m("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[l(
|
|
325
|
+
contractspec validate src/contracts/mySpec.ts`})]}),m("div",{className:"card-subtle space-y-3 p-6",children:[l("h2",{className:"font-bold text-2xl",children:"Still blocked?"}),m("ul",{className:"space-y-2 text-muted-foreground",children:[l("li",{children:"Confirm compatibility requirements for runtime and framework."}),l("li",{children:"Re-run builds on a clean branch to isolate changes."}),l("li",{children:"Use a new spec and minimal adapter to validate setup."})]})]})]}),m("div",{className:"flex flex-wrap items-center gap-3 pt-2",children:[l(V,{href:"/docs/getting-started/start-here",className:"btn-ghost",children:"Start here"}),l(V,{href:"/docs/getting-started/compatibility",className:"btn-ghost",children:"Compatibility"}),m(V,{href:"/docs/getting-started/installation",className:"btn-primary",children:["Next: Installation ",l(ye,{size:16})]})]})]})}import{CodeBlock as Ce}from"@contractspec/lib.design-system";import U from"@contractspec/lib.ui-link";import{ChevronRight as we,ExternalLink as Se}from"lucide-react";import{jsx as e,jsxs as a}from"react/jsx-runtime";function Ct(){let g=[{category:"Core Functionality",items:["Real-time validation with instant feedback on spec errors","Build/Scaffold handlers and components from specs","Interactive spec creation wizard","Watch mode for auto-rebuild on changes","Sync all specs in workspace with one command"]},{category:"Visual Navigation",items:["Specs Explorer sidebar with organized tree view","Dependencies view to visualize spec relationships","Build Results tracking with history","Circular dependency detection"]},{category:"Comparison & Export",items:["Semantic and text diff between specs","Git comparison with baseline branches","OpenAPI 3.1 specification export"]}],r=[{name:"Create New Spec",description:"Interactive wizard to create specs"},{name:"Validate Current Spec",description:"Validate the currently open spec"},{name:"Build/Scaffold from Current Spec",description:"Generate handler/component"},{name:"Toggle Watch Mode",description:"Auto-rebuild on changes"},{name:"Sync All Specs",description:"Build all specs in workspace"},{name:"Analyze Spec Dependencies",description:"Visualize spec dependencies"},{name:"Compare Specs",description:"Semantic or text diff between specs"},{name:"Export to OpenAPI",description:"Generate OpenAPI specification"}];return a("div",{className:"space-y-8",children:[a("div",{className:"space-y-2",children:[e("h1",{className:"font-bold text-4xl",children:"VS Code Extension"}),e("p",{className:"text-lg text-muted-foreground",children:"Spec-first development directly in VS Code. Validate, scaffold, and explore your contract specifications with real-time feedback."})]}),a("div",{className:"flex flex-wrap gap-3",children:[a("a",{href:"https://marketplace.visualstudio.com/items?itemName=lssm.vscode-contractspec",target:"_blank",rel:"noopener noreferrer",className:"btn-primary inline-flex items-center gap-2",children:["Install Extension ",e(Se,{size:16})]}),e("a",{href:"vscode:extension/lssm.vscode-contractspec",className:"btn-ghost inline-flex items-center gap-2",children:"Open in VS Code"})]}),a("div",{className:"space-y-6",children:[a("div",{className:"space-y-3",children:[e("h2",{className:"font-bold text-2xl",children:"Installation"}),a("div",{className:"space-y-2",children:[a("p",{className:"text-muted-foreground text-sm",children:[e("strong",{children:"Option 1:"})," Install from VS Code Marketplace"]}),e(Ce,{language:"bash",code:"code --install-extension lssm.vscode-contractspec"}),a("p",{className:"mt-4 text-muted-foreground text-sm",children:[e("strong",{children:"Option 2:"}),' Search for "ContractSpec" in VS Code Extensions (Ctrl/Cmd+Shift+X)']})]})]}),a("div",{className:"space-y-4",children:[e("h2",{className:"font-bold text-2xl",children:"Features"}),e("div",{className:"grid gap-4 md:grid-cols-3",children:g.map((h)=>a("div",{className:"card-subtle space-y-3 p-4",children:[e("h3",{className:"font-bold text-violet-400",children:h.category}),e("ul",{className:"space-y-2",children:h.items.map((I)=>a("li",{className:"flex items-start gap-2 text-muted-foreground text-sm",children:[e("span",{className:"mt-1 text-violet-400",children:"-"}),e("span",{children:I})]},I))})]},h.category))})]}),a("div",{className:"space-y-4",children:[e("h2",{className:"font-bold text-2xl",children:"Commands"}),a("p",{className:"text-muted-foreground",children:["Access commands via Command Palette (Ctrl/Cmd+Shift+P) with prefix"," ",e("code",{children:"ContractSpec:"})]}),e("div",{className:"grid gap-3 md:grid-cols-2",children:r.map((h)=>e("div",{className:"card-subtle flex items-center gap-3 p-3",children:a("div",{className:"flex-1",children:[e("p",{className:"font-medium font-mono text-sm",children:h.name}),e("p",{className:"text-muted-foreground text-xs",children:h.description})]})},h.name))})]}),a("div",{className:"space-y-3",children:[e("h2",{className:"font-bold text-2xl",children:"Sidebar Views"}),e("p",{className:"text-muted-foreground",children:"The extension adds a ContractSpec activity bar (icon in sidebar) with three views:"}),a("div",{className:"grid gap-4 md:grid-cols-3",children:[a("div",{className:"card-subtle space-y-2 p-4",children:[e("h4",{className:"font-bold",children:"Specs Explorer"}),e("p",{className:"text-muted-foreground text-sm",children:"Browse all specs organized by type. Shows name, version, and stability. Click to open, right-click for actions."})]}),a("div",{className:"card-subtle space-y-2 p-4",children:[e("h4",{className:"font-bold",children:"Dependencies"}),e("p",{className:"text-muted-foreground text-sm",children:"Visualize spec relationships. Detect circular dependencies. Navigate to referenced specs."})]}),a("div",{className:"card-subtle space-y-2 p-4",children:[e("h4",{className:"font-bold",children:"Build Results"}),e("p",{className:"text-muted-foreground text-sm",children:"Track build history (last 20). Success/failure indicators. Click to open generated files."})]})]})]}),a("div",{className:"space-y-3",children:[e("h2",{className:"font-bold text-2xl",children:"Getting Started"}),a("ol",{className:"list-inside list-decimal space-y-2 text-muted-foreground",children:[e("li",{children:"Install the extension from VS Code Marketplace"}),e("li",{children:"Open a workspace with ContractSpec files (or create one)"}),e("li",{children:"Start the walkthrough: Help - Welcome - ContractSpec"}),a("li",{children:["Create your first spec: Click ",e("strong",{children:"+"})," in Specs Explorer or run ",e("code",{children:"ContractSpec: Create New Spec"})]}),e("li",{children:"Build from it: Click the build icon in the editor title bar"})]})]}),a("div",{className:"card-subtle space-y-4 p-6",children:[e("h3",{className:"font-bold",children:"Configuration"}),e("p",{className:"text-muted-foreground text-sm",children:"Configure the extension in VS Code Settings:"}),e("div",{className:"overflow-x-auto",children:a("table",{className:"w-full text-muted-foreground text-sm",children:[e("thead",{children:a("tr",{className:"border-border border-b",children:[e("th",{className:"p-2 text-left font-medium",children:"Setting"}),e("th",{className:"p-2 text-left font-medium",children:"Description"}),e("th",{className:"p-2 text-left font-medium",children:"Default"})]})}),a("tbody",{children:[a("tr",{className:"border-border border-b",children:[e("td",{className:"p-2 font-mono text-xs",children:"validation.onSave"}),e("td",{className:"p-2",children:"Run validation on save"}),e("td",{className:"p-2",children:"true"})]}),a("tr",{className:"border-border border-b",children:[e("td",{className:"p-2 font-mono text-xs",children:"validation.onOpen"}),e("td",{className:"p-2",children:"Run validation on open"}),e("td",{className:"p-2",children:"true"})]}),a("tr",{className:"border-border border-b",children:[e("td",{className:"p-2 font-mono text-xs",children:"api.baseUrl"}),e("td",{className:"p-2",children:"Base URL for ContractSpec API"}),e("td",{className:"p-2",children:"(empty)"})]})]})]})})]})]}),a("div",{className:"flex items-center gap-4 pt-4",children:[e(U,{href:"/docs/getting-started/tools/cli",className:"btn-ghost",children:"Back: CLI"}),a(U,{href:"/docs/specs",className:"btn-primary",children:["Next: Core Concepts ",e(we,{size:16})]})]})]})}import{registerDocBlocks as Ie}from"@contractspec/lib.contracts-spec/docs";var ke=[{id:"docs.getting-started.start-here",title:"Start here",summary:"Fast onboarding path from install to first generated contract.",kind:"usage",visibility:"public",route:"/docs/getting-started/start-here",tags:["getting-started","onboarding"],body:`# Start Here
|
|
251
326
|
|
|
252
327
|
Get ContractSpec running quickly and generate your first contract-backed code.
|
|
253
328
|
|
|
@@ -346,4 +421,4 @@ ContractSpec supports modern TypeScript stacks with spec-first workflows.
|
|
|
346
421
|
|
|
347
422
|
- PostgreSQL via Prisma
|
|
348
423
|
- Bring your own adapter for other databases
|
|
349
|
-
`}];
|
|
424
|
+
`}];Ie(ke);export{Ct as VSCodeExtensionPage,be as TroubleshootingPage,ve as StartHerePage,fe as InstallationPage,pe as HelloWorldPage,Ke as DeveloperToolsPage,ae as DataViewTutorialPage,K as CompatibilityPage,Y as CLIPage};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const accountImportTemplateCode = "import {\n createImportPlan,\n createRecordBatch,\n defineDataExchangeTemplate,\n previewImport,\n} from \"@contractspec/lib.data-exchange-core\";\nimport { defineSchemaModel, ScalarTypeEnum } from \"@contractspec/lib.schema\";\n\nconst AccountImportSchema = defineSchemaModel({\n name: \"AccountImport\",\n fields: {\n id: { type: ScalarTypeEnum.ID(), isOptional: false },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n amount: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },\n active: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n tags: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n});\n\nconst accountImportTemplate = defineDataExchangeTemplate({\n key: \"accounts.import\",\n version: \"1.0.0\",\n title: \"Account import\",\n columns: [\n {\n key: \"id\",\n label: \"Account ID\",\n targetField: \"id\",\n required: true,\n sourceAliases: [\"Account Identifier\", \"External ID\", \"No compte\"],\n },\n {\n key: \"status\",\n label: \"Status\",\n targetField: \"status\",\n required: true,\n sourceAliases: [\"Statut\", \"State\"],\n format: { kind: \"text\", trim: true, case: \"lowercase\" },\n },\n {\n key: \"amount\",\n label: \"Amount\",\n targetField: \"amount\",\n required: true,\n sourceAliases: [\"Montant\", \"Balance\"],\n format: { kind: \"number\", decimalSeparator: \",\", thousandsSeparator: \".\" },\n },\n {\n key: \"active\",\n label: \"Active\",\n targetField: \"active\",\n sourceAliases: [\"Actif\", \"Enabled\"],\n format: { kind: \"boolean\", trueValues: [\"yes\", \"oui\"], falseValues: [\"no\", \"non\"] },\n },\n {\n key: \"tags\",\n label: \"Tags\",\n targetField: \"tags\",\n format: { kind: \"split\", delimiter: \";\" },\n },\n ],\n});\n\nconst sourceBatch = createRecordBatch([\n {\n \"No compte\": \"acc-1\",\n Statut: \" Active \",\n Montant: \"1.234,50\",\n Actif: \"oui\",\n Tags: \"vip; beta\",\n },\n]);\n\nconst preview = previewImport(\n createImportPlan({\n source: { kind: \"memory\", batch: sourceBatch, format: \"csv\" },\n target: { kind: \"memory\", format: \"json\" },\n schema: AccountImportSchema,\n sourceBatch,\n template: accountImportTemplate,\n }),\n);\n\nconsole.log(preview.plan.mappingSource); // \"template\"\nconsole.log(preview.normalizedRecords[0]);";
|
|
2
|
+
export declare const serverDryRunCode = "import { defineDataExchangeTemplate } from \"@contractspec/lib.data-exchange-core\";\nimport { dryRunImport, executeImport } from \"@contractspec/lib.data-exchange-server\";\n\nconst template = defineDataExchangeTemplate({\n key: \"accounts.import\",\n version: \"1.0.0\",\n columns: [\n { key: \"id\", label: \"Account ID\", targetField: \"id\", required: true, sourceAliases: [\"Account Identifier\"] },\n { key: \"amount\", label: \"Amount\", targetField: \"amount\", format: { kind: \"currency\", currencySymbol: \"\u20AC\", decimalSeparator: \",\" } },\n ],\n});\n\nconst partnerSource = {\n kind: \"file\",\n path: \"partner-accounts.csv\",\n format: \"csv\",\n codecOptions: { csv: { delimiter: \";\", skipRows: 1 } },\n} as const;\n\nconst formatProfile = {\n columns: {\n amount: { kind: \"currency\", currencySymbol: \"\u20AC\", decimalSeparator: \",\" },\n },\n} as const;\n\nconst preview = await dryRunImport({\n source: partnerSource,\n target: { kind: \"memory\", format: \"json\" },\n schema: AccountImportSchema,\n template,\n formatProfile,\n});\n\nconst blockingIssues = preview.issues.filter((issue) => issue.severity === \"error\");\n\nif (blockingIssues.length === 0) {\n await executeImport({\n source: partnerSource,\n target: { kind: \"memory\", format: \"json\" },\n schema: AccountImportSchema,\n template,\n formatProfile,\n });\n}";
|
|
3
|
+
export declare const clientReviewCode = "\"use client\";\n\nimport { useDataExchangeController } from \"@contractspec/lib.data-exchange-client\";\n\nexport function ImportMappingReview({ preview }) {\n const controller = useDataExchangeController({ preview });\n const replacementSourceColumn = controller.model.ignoredSourceColumns[0];\n\n return (\n <section>\n {controller.model.templateRows.map((row) => (\n <button\n key={row.id}\n type=\"button\"\n disabled={!replacementSourceColumn}\n onClick={() => {\n if (!replacementSourceColumn) return;\n controller.selectAlias(row.targetField, replacementSourceColumn);\n }}\n >\n {row.label}: {row.sourceField || \"Unmatched\"} -> {row.targetField}\n {row.required ? \" required\" : \"\"}\n {row.formatLabel ? ` (${row.formatLabel})` : \"\"}\n </button>\n ))}\n {controller.model.unmatchedRequiredRows.length > 0 ? (\n <p>Resolve required columns before import.</p>\n ) : null}\n </section>\n );\n}";
|
|
4
|
+
export declare const developerPrompt = "You are adding an import flow to a ContractSpec app.\n\nDefine a reusable data-exchange template for this canonical schema:\n- target fields, required flags, and display labels\n- known partner column aliases\n- value formats for numbers, dates, booleans, JSON, split/join lists, currency, and percentages\n\nWire the template into core preview planning and server dry-run execution. Keep explicit mappings higher precedence than template resolution. Return the template, preview call, server dry-run call, and tests for alias matching plus localized formatting.";
|
|
5
|
+
export declare const partnerPrompt = "A partner sent a CSV/JSON/XML file that does not match our recommended import template.\n\nCompare the incoming headers and value samples against this ContractSpec data-exchange template. Propose:\n- source-to-target column matches with confidence\n- missing required target fields\n- ignored source columns\n- format overrides for localized numbers, booleans, dates, JSON, split/join lists, currency, or percentages\n\nDo not execute the import. Produce a dry-run plan and the user-facing review copy.";
|
|
6
|
+
export declare const verificationCode = "cd packages/libs/data-exchange-core && bun test && bun run typecheck && bun run lint:check\ncd packages/libs/data-exchange-client && bun test && bun run typecheck && bun run lint:check\ncd packages/libs/data-exchange-server && bun test && bun run typecheck && bun run lint:check";
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var a=Object.defineProperty;var o=(e)=>e;function n(e,t){this[e]=o.bind(null,t)}var c=(e,t)=>{for(var r in t)a(e,r,{get:t[r],enumerable:!0,configurable:!0,set:n.bind(t,r)})};var i=(e,t)=>()=>(e&&(t=e(e=0)),t);var s=`import {
|
|
3
|
+
createImportPlan,
|
|
4
|
+
createRecordBatch,
|
|
5
|
+
defineDataExchangeTemplate,
|
|
6
|
+
previewImport,
|
|
7
|
+
} from "@contractspec/lib.data-exchange-core";
|
|
8
|
+
import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
|
|
9
|
+
|
|
10
|
+
const AccountImportSchema = defineSchemaModel({
|
|
11
|
+
name: "AccountImport",
|
|
12
|
+
fields: {
|
|
13
|
+
id: { type: ScalarTypeEnum.ID(), isOptional: false },
|
|
14
|
+
status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
15
|
+
amount: { type: ScalarTypeEnum.Float_unsecure(), isOptional: false },
|
|
16
|
+
active: { type: ScalarTypeEnum.Boolean(), isOptional: false },
|
|
17
|
+
tags: { type: ScalarTypeEnum.JSON(), isOptional: true },
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const accountImportTemplate = defineDataExchangeTemplate({
|
|
22
|
+
key: "accounts.import",
|
|
23
|
+
version: "1.0.0",
|
|
24
|
+
title: "Account import",
|
|
25
|
+
columns: [
|
|
26
|
+
{
|
|
27
|
+
key: "id",
|
|
28
|
+
label: "Account ID",
|
|
29
|
+
targetField: "id",
|
|
30
|
+
required: true,
|
|
31
|
+
sourceAliases: ["Account Identifier", "External ID", "No compte"],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: "status",
|
|
35
|
+
label: "Status",
|
|
36
|
+
targetField: "status",
|
|
37
|
+
required: true,
|
|
38
|
+
sourceAliases: ["Statut", "State"],
|
|
39
|
+
format: { kind: "text", trim: true, case: "lowercase" },
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: "amount",
|
|
43
|
+
label: "Amount",
|
|
44
|
+
targetField: "amount",
|
|
45
|
+
required: true,
|
|
46
|
+
sourceAliases: ["Montant", "Balance"],
|
|
47
|
+
format: { kind: "number", decimalSeparator: ",", thousandsSeparator: "." },
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
key: "active",
|
|
51
|
+
label: "Active",
|
|
52
|
+
targetField: "active",
|
|
53
|
+
sourceAliases: ["Actif", "Enabled"],
|
|
54
|
+
format: { kind: "boolean", trueValues: ["yes", "oui"], falseValues: ["no", "non"] },
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
key: "tags",
|
|
58
|
+
label: "Tags",
|
|
59
|
+
targetField: "tags",
|
|
60
|
+
format: { kind: "split", delimiter: ";" },
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const sourceBatch = createRecordBatch([
|
|
66
|
+
{
|
|
67
|
+
"No compte": "acc-1",
|
|
68
|
+
Statut: " Active ",
|
|
69
|
+
Montant: "1.234,50",
|
|
70
|
+
Actif: "oui",
|
|
71
|
+
Tags: "vip; beta",
|
|
72
|
+
},
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
const preview = previewImport(
|
|
76
|
+
createImportPlan({
|
|
77
|
+
source: { kind: "memory", batch: sourceBatch, format: "csv" },
|
|
78
|
+
target: { kind: "memory", format: "json" },
|
|
79
|
+
schema: AccountImportSchema,
|
|
80
|
+
sourceBatch,
|
|
81
|
+
template: accountImportTemplate,
|
|
82
|
+
}),
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
console.log(preview.plan.mappingSource); // "template"
|
|
86
|
+
console.log(preview.normalizedRecords[0]);`,u=`import { defineDataExchangeTemplate } from "@contractspec/lib.data-exchange-core";
|
|
87
|
+
import { dryRunImport, executeImport } from "@contractspec/lib.data-exchange-server";
|
|
88
|
+
|
|
89
|
+
const template = defineDataExchangeTemplate({
|
|
90
|
+
key: "accounts.import",
|
|
91
|
+
version: "1.0.0",
|
|
92
|
+
columns: [
|
|
93
|
+
{ key: "id", label: "Account ID", targetField: "id", required: true, sourceAliases: ["Account Identifier"] },
|
|
94
|
+
{ key: "amount", label: "Amount", targetField: "amount", format: { kind: "currency", currencySymbol: "\u20AC", decimalSeparator: "," } },
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const partnerSource = {
|
|
99
|
+
kind: "file",
|
|
100
|
+
path: "partner-accounts.csv",
|
|
101
|
+
format: "csv",
|
|
102
|
+
codecOptions: { csv: { delimiter: ";", skipRows: 1 } },
|
|
103
|
+
} as const;
|
|
104
|
+
|
|
105
|
+
const formatProfile = {
|
|
106
|
+
columns: {
|
|
107
|
+
amount: { kind: "currency", currencySymbol: "\u20AC", decimalSeparator: "," },
|
|
108
|
+
},
|
|
109
|
+
} as const;
|
|
110
|
+
|
|
111
|
+
const preview = await dryRunImport({
|
|
112
|
+
source: partnerSource,
|
|
113
|
+
target: { kind: "memory", format: "json" },
|
|
114
|
+
schema: AccountImportSchema,
|
|
115
|
+
template,
|
|
116
|
+
formatProfile,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const blockingIssues = preview.issues.filter((issue) => issue.severity === "error");
|
|
120
|
+
|
|
121
|
+
if (blockingIssues.length === 0) {
|
|
122
|
+
await executeImport({
|
|
123
|
+
source: partnerSource,
|
|
124
|
+
target: { kind: "memory", format: "json" },
|
|
125
|
+
schema: AccountImportSchema,
|
|
126
|
+
template,
|
|
127
|
+
formatProfile,
|
|
128
|
+
});
|
|
129
|
+
}`,m=`"use client";
|
|
130
|
+
|
|
131
|
+
import { useDataExchangeController } from "@contractspec/lib.data-exchange-client";
|
|
132
|
+
|
|
133
|
+
export function ImportMappingReview({ preview }) {
|
|
134
|
+
const controller = useDataExchangeController({ preview });
|
|
135
|
+
const replacementSourceColumn = controller.model.ignoredSourceColumns[0];
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<section>
|
|
139
|
+
{controller.model.templateRows.map((row) => (
|
|
140
|
+
<button
|
|
141
|
+
key={row.id}
|
|
142
|
+
type="button"
|
|
143
|
+
disabled={!replacementSourceColumn}
|
|
144
|
+
onClick={() => {
|
|
145
|
+
if (!replacementSourceColumn) return;
|
|
146
|
+
controller.selectAlias(row.targetField, replacementSourceColumn);
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
{row.label}: {row.sourceField || "Unmatched"} -> {row.targetField}
|
|
150
|
+
{row.required ? " required" : ""}
|
|
151
|
+
{row.formatLabel ? \` (\${row.formatLabel})\` : ""}
|
|
152
|
+
</button>
|
|
153
|
+
))}
|
|
154
|
+
{controller.model.unmatchedRequiredRows.length > 0 ? (
|
|
155
|
+
<p>Resolve required columns before import.</p>
|
|
156
|
+
) : null}
|
|
157
|
+
</section>
|
|
158
|
+
);
|
|
159
|
+
}`,p=`You are adding an import flow to a ContractSpec app.
|
|
160
|
+
|
|
161
|
+
Define a reusable data-exchange template for this canonical schema:
|
|
162
|
+
- target fields, required flags, and display labels
|
|
163
|
+
- known partner column aliases
|
|
164
|
+
- value formats for numbers, dates, booleans, JSON, split/join lists, currency, and percentages
|
|
165
|
+
|
|
166
|
+
Wire the template into core preview planning and server dry-run execution. Keep explicit mappings higher precedence than template resolution. Return the template, preview call, server dry-run call, and tests for alias matching plus localized formatting.`,d=`A partner sent a CSV/JSON/XML file that does not match our recommended import template.
|
|
167
|
+
|
|
168
|
+
Compare the incoming headers and value samples against this ContractSpec data-exchange template. Propose:
|
|
169
|
+
- source-to-target column matches with confidence
|
|
170
|
+
- missing required target fields
|
|
171
|
+
- ignored source columns
|
|
172
|
+
- format overrides for localized numbers, booleans, dates, JSON, split/join lists, currency, or percentages
|
|
173
|
+
|
|
174
|
+
Do not execute the import. Produce a dry-run plan and the user-facing review copy.`,g=`cd packages/libs/data-exchange-core && bun test && bun run typecheck && bun run lint:check
|
|
175
|
+
cd packages/libs/data-exchange-client && bun test && bun run typecheck && bun run lint:check
|
|
176
|
+
cd packages/libs/data-exchange-server && bun test && bun run typecheck && bun run lint:check`;export{g as verificationCode,u as serverDryRunCode,d as partnerPrompt,p as developerPrompt,m as clientReviewCode,s as accountImportTemplateCode};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function GuideDataExchangeImportTemplatesPage(): import("react/jsx-runtime").JSX.Element;
|