digital-products 2.1.3 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -5
- package/CHANGELOG.md +17 -0
- package/README.md +2 -0
- package/dist/api.js +7 -7
- package/dist/api.js.map +1 -1
- package/dist/app.js +6 -6
- package/dist/app.js.map +1 -1
- package/dist/client.d.ts +157 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +69 -0
- package/dist/client.js.map +1 -0
- package/dist/content.js +7 -7
- package/dist/content.js.map +1 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +6 -6
- package/dist/data.js.map +1 -1
- package/dist/dataset.js +5 -5
- package/dist/dataset.js.map +1 -1
- package/dist/index.d.ts +92 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +139 -15
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +17 -10
- package/dist/mcp.js.map +1 -1
- package/dist/product.js +2 -2
- package/dist/product.js.map +1 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +52 -16
- package/dist/sdk.js.map +1 -1
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +12 -8
- package/dist/site.js.map +1 -1
- package/dist/types.d.ts +830 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +495 -2
- package/dist/types.js.map +1 -1
- package/dist/worker.d.ts +205 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +356 -0
- package/dist/worker.js.map +1 -0
- package/package.json +29 -13
- package/src/api.ts +7 -7
- package/src/app.ts +6 -6
- package/src/client.ts +192 -0
- package/src/content.ts +7 -7
- package/src/data.ts +12 -7
- package/src/dataset.ts +5 -5
- package/src/index.ts +151 -15
- package/src/mcp.ts +18 -11
- package/src/product.ts +2 -2
- package/src/sdk.ts +54 -15
- package/src/site.ts +12 -8
- package/src/types.ts +821 -12
- package/src/worker.ts +525 -0
- package/test/product.test.ts +53 -198
- package/test/unified-types.test.ts +589 -0
- package/test/worker.test.ts +912 -0
- package/vitest.config.ts +42 -0
- package/wrangler.jsonc +36 -0
- package/LICENSE +0 -21
- package/dist/features/define.d.ts +0 -63
- package/dist/features/define.d.ts.map +0 -1
- package/dist/features/define.js +0 -72
- package/dist/features/define.js.map +0 -1
- package/dist/features/flags.d.ts +0 -98
- package/dist/features/flags.d.ts.map +0 -1
- package/dist/features/flags.js +0 -145
- package/dist/features/flags.js.map +0 -1
- package/dist/features/toggles.d.ts +0 -75
- package/dist/features/toggles.d.ts.map +0 -1
- package/dist/features/toggles.js +0 -107
- package/dist/features/toggles.js.map +0 -1
- package/dist/tiers/define.d.ts +0 -63
- package/dist/tiers/define.d.ts.map +0 -1
- package/dist/tiers/define.js +0 -78
- package/dist/tiers/define.js.map +0 -1
- package/dist/tiers/entitlements.d.ts +0 -94
- package/dist/tiers/entitlements.d.ts.map +0 -1
- package/dist/tiers/entitlements.js +0 -94
- package/dist/tiers/entitlements.js.map +0 -1
- package/src/api.js +0 -128
- package/src/app.js +0 -106
- package/src/content.js +0 -77
- package/src/data.js +0 -106
- package/src/dataset.js +0 -49
- package/src/entities/ai.js +0 -858
- package/src/entities/content.js +0 -783
- package/src/entities/index.js +0 -88
- package/src/entities/interfaces.js +0 -929
- package/src/entities/lifecycle.js +0 -803
- package/src/entities/products.js +0 -797
- package/src/entities/web.js +0 -657
- package/src/features/define.ts +0 -130
- package/src/features/flags.ts +0 -247
- package/src/features/toggles.ts +0 -189
- package/src/index.js +0 -35
- package/src/mcp.js +0 -139
- package/src/pricing/billing.ts +0 -386
- package/src/pricing/plans.ts +0 -214
- package/src/product.js +0 -53
- package/src/registry.js +0 -31
- package/src/sdk.js +0 -127
- package/src/site.js +0 -112
- package/src/tiers/define.ts +0 -137
- package/src/tiers/entitlements.ts +0 -201
- package/src/types.js +0 -4
- package/test/analytics/events.test.ts +0 -319
- package/test/analytics/experiments.test.ts +0 -327
- package/test/features/define.test.ts +0 -187
- package/test/features/flags.test.ts +0 -259
- package/test/features/toggles.test.ts +0 -178
- package/test/lifecycle/stages.test.ts +0 -233
- package/test/lifecycle/transitions.test.ts +0 -207
- package/test/onboarding/flows.test.ts +0 -307
- package/test/pricing/billing.test.ts +0 -287
- package/test/pricing/plans.test.ts +0 -307
- package/test/roadmap/milestones.test.ts +0 -231
- package/test/roadmap/priorities.test.ts +0 -239
- package/test/tiers/define.test.ts +0 -192
- package/test/tiers/entitlements.test.ts +0 -220
package/src/client.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC Client for Digital Products
|
|
3
|
+
*
|
|
4
|
+
* Provides a typed RPC client that connects to the deployed
|
|
5
|
+
* digital-products worker using rpc.do for remote procedure calls.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createDigitalProductsClient } from 'digital-products/client'
|
|
10
|
+
*
|
|
11
|
+
* const client = createDigitalProductsClient('https://digital-products.workers.dev')
|
|
12
|
+
* const product = await client.create({ name: 'My Product', description: 'A great product', version: '1.0.0' })
|
|
13
|
+
* const feature = await client.addFeature(product.id, { name: 'Search', description: 'Full-text search' })
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { RPC, http } from 'rpc.do'
|
|
20
|
+
|
|
21
|
+
// ==================== Types ====================
|
|
22
|
+
|
|
23
|
+
interface ProductData {
|
|
24
|
+
id: string
|
|
25
|
+
name: string
|
|
26
|
+
description: string
|
|
27
|
+
version: string
|
|
28
|
+
status: 'draft' | 'active' | 'deprecated' | 'archived'
|
|
29
|
+
type?: string
|
|
30
|
+
features?: FeatureData[]
|
|
31
|
+
metadata?: Record<string, unknown>
|
|
32
|
+
tags?: string[]
|
|
33
|
+
createdAt: Date
|
|
34
|
+
updatedAt: Date
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface FeatureData {
|
|
38
|
+
id: string
|
|
39
|
+
name: string
|
|
40
|
+
description: string
|
|
41
|
+
status: 'draft' | 'beta' | 'ga' | 'deprecated'
|
|
42
|
+
productId: string
|
|
43
|
+
metadata?: Record<string, unknown>
|
|
44
|
+
createdAt: Date
|
|
45
|
+
updatedAt: Date
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface VersionData {
|
|
49
|
+
id: string
|
|
50
|
+
productId: string
|
|
51
|
+
version: string
|
|
52
|
+
changelog?: string
|
|
53
|
+
status: 'draft' | 'published' | 'deprecated'
|
|
54
|
+
features?: string[]
|
|
55
|
+
metadata?: Record<string, unknown>
|
|
56
|
+
createdAt: Date
|
|
57
|
+
publishedAt?: Date
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface BundleData {
|
|
61
|
+
id: string
|
|
62
|
+
name: string
|
|
63
|
+
description: string
|
|
64
|
+
productIds: string[]
|
|
65
|
+
pricing?: PricingData
|
|
66
|
+
metadata?: Record<string, unknown>
|
|
67
|
+
createdAt: Date
|
|
68
|
+
updatedAt: Date
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface PricingData {
|
|
72
|
+
model: 'free' | 'one-time' | 'subscription' | 'usage-based'
|
|
73
|
+
amount?: number
|
|
74
|
+
currency?: string
|
|
75
|
+
interval?: 'month' | 'year'
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface ListOptions {
|
|
79
|
+
limit?: number
|
|
80
|
+
offset?: number
|
|
81
|
+
status?: string
|
|
82
|
+
type?: string
|
|
83
|
+
orderBy?: string
|
|
84
|
+
order?: 'asc' | 'desc'
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ==================== API Type ====================
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* DigitalProductsAPI - Type-safe interface matching ProductServiceCore RPC methods
|
|
91
|
+
*
|
|
92
|
+
* This interface mirrors all public methods on ProductServiceCore so that
|
|
93
|
+
* the RPC client provides full type safety when calling remote methods.
|
|
94
|
+
*/
|
|
95
|
+
export interface DigitalProductsAPI {
|
|
96
|
+
// Product CRUD
|
|
97
|
+
create(data: Partial<ProductData>): Promise<ProductData>
|
|
98
|
+
get(id: string): Promise<ProductData | null>
|
|
99
|
+
update(id: string, data: Partial<ProductData>): Promise<ProductData>
|
|
100
|
+
delete(id: string): Promise<boolean>
|
|
101
|
+
list(options?: ListOptions): Promise<ProductData[]>
|
|
102
|
+
|
|
103
|
+
// Feature Operations
|
|
104
|
+
addFeature(productId: string, featureData: Partial<FeatureData>): Promise<FeatureData>
|
|
105
|
+
updateFeature(featureId: string, data: Partial<FeatureData>): Promise<FeatureData>
|
|
106
|
+
removeFeature(featureId: string): Promise<boolean>
|
|
107
|
+
listFeatures(productId: string): Promise<FeatureData[]>
|
|
108
|
+
|
|
109
|
+
// Version Operations
|
|
110
|
+
publish(productId: string, versionStr: string, changelog?: string): Promise<VersionData>
|
|
111
|
+
listVersions(productId: string): Promise<VersionData[]>
|
|
112
|
+
getVersion(productId: string, versionStr: string): Promise<VersionData | null>
|
|
113
|
+
deprecateVersion(productId: string, versionStr: string): Promise<VersionData>
|
|
114
|
+
|
|
115
|
+
// Bundle Operations
|
|
116
|
+
compose(name: string, productIds: string[], options?: Partial<BundleData>): Promise<BundleData>
|
|
117
|
+
getBundle(bundleId: string): Promise<BundleData | null>
|
|
118
|
+
updateBundle(bundleId: string, data: Partial<BundleData>): Promise<BundleData>
|
|
119
|
+
listBundles(): Promise<BundleData[]>
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ==================== Client Options ====================
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Options for creating a digital products RPC client
|
|
126
|
+
*/
|
|
127
|
+
export interface DigitalProductsClientOptions {
|
|
128
|
+
/** Authentication token or API key */
|
|
129
|
+
token?: string
|
|
130
|
+
/** Request timeout in milliseconds */
|
|
131
|
+
timeout?: number
|
|
132
|
+
/** Custom headers to include in requests */
|
|
133
|
+
headers?: Record<string, string>
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ==================== Client Factory ====================
|
|
137
|
+
|
|
138
|
+
/** Default URL for the digital-products worker */
|
|
139
|
+
const DEFAULT_URL = 'https://digital-products.workers.dev'
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Create a typed RPC client for the digital-products worker
|
|
143
|
+
*
|
|
144
|
+
* @param url - The URL of the deployed digital-products worker
|
|
145
|
+
* @param options - Optional client configuration
|
|
146
|
+
* @returns A typed RPC client with all ProductServiceCore methods
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* import { createDigitalProductsClient } from 'digital-products/client'
|
|
151
|
+
*
|
|
152
|
+
* // Connect to production
|
|
153
|
+
* const client = createDigitalProductsClient('https://digital-products.workers.dev')
|
|
154
|
+
*
|
|
155
|
+
* // Create a product
|
|
156
|
+
* const product = await client.create({
|
|
157
|
+
* name: 'My API',
|
|
158
|
+
* description: 'A powerful API service',
|
|
159
|
+
* version: '1.0.0',
|
|
160
|
+
* })
|
|
161
|
+
*
|
|
162
|
+
* // Add features
|
|
163
|
+
* await client.addFeature(product.id, { name: 'Rate Limiting', description: 'API rate limiting' })
|
|
164
|
+
* await client.addFeature(product.id, { name: 'Analytics', description: 'Usage analytics' })
|
|
165
|
+
*
|
|
166
|
+
* // Publish a version
|
|
167
|
+
* await client.publish(product.id, '1.0.0', 'Initial release')
|
|
168
|
+
*
|
|
169
|
+
* // Create a bundle
|
|
170
|
+
* const bundle = await client.compose('Enterprise Bundle', [product.id, otherProduct.id])
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export function createDigitalProductsClient(
|
|
174
|
+
url: string = DEFAULT_URL,
|
|
175
|
+
options?: DigitalProductsClientOptions
|
|
176
|
+
) {
|
|
177
|
+
return RPC<DigitalProductsAPI>(http(url, options?.token))
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Default client instance connected to the production digital-products worker
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* import client from 'digital-products/client'
|
|
186
|
+
*
|
|
187
|
+
* const product = await client.create({ name: 'My Product', description: 'Great', version: '1.0.0' })
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
const client = createDigitalProductsClient()
|
|
191
|
+
|
|
192
|
+
export default client
|
package/src/content.ts
CHANGED
|
@@ -44,14 +44,14 @@ export function Content(config: Omit<ContentDefinition, 'type'>): ContentDefinit
|
|
|
44
44
|
description: config.description,
|
|
45
45
|
version: config.version,
|
|
46
46
|
format: config.format || 'markdown',
|
|
47
|
-
source: config.source,
|
|
48
|
-
schema: config.schema,
|
|
49
|
-
frontmatter: config.frontmatter,
|
|
50
|
-
categories: config.categories,
|
|
51
|
-
workflow: config.workflow,
|
|
52
|
-
metadata: config.metadata,
|
|
53
|
-
tags: config.tags,
|
|
54
47
|
status: config.status || 'active',
|
|
48
|
+
...(config.source !== undefined && { source: config.source }),
|
|
49
|
+
...(config.schema !== undefined && { schema: config.schema }),
|
|
50
|
+
...(config.frontmatter !== undefined && { frontmatter: config.frontmatter }),
|
|
51
|
+
...(config.categories !== undefined && { categories: config.categories }),
|
|
52
|
+
...(config.workflow !== undefined && { workflow: config.workflow }),
|
|
53
|
+
...(config.metadata !== undefined && { metadata: config.metadata }),
|
|
54
|
+
...(config.tags !== undefined && { tags: config.tags }),
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
return registerProduct(content)
|
package/src/data.ts
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* Data() - Define structured data
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
DataDefinition,
|
|
7
|
+
IndexDefinition,
|
|
8
|
+
RelationshipDefinition,
|
|
9
|
+
ValidationRule,
|
|
10
|
+
} from './types.js'
|
|
6
11
|
import type { SimpleSchema } from 'ai-functions'
|
|
7
12
|
import { registerProduct } from './product.js'
|
|
8
13
|
|
|
@@ -44,12 +49,12 @@ export function Data(config: Omit<DataDefinition, 'type'>): DataDefinition {
|
|
|
44
49
|
version: config.version,
|
|
45
50
|
schema: config.schema,
|
|
46
51
|
provider: config.provider || 'fs',
|
|
47
|
-
indexes: config.indexes,
|
|
48
|
-
relationships: config.relationships,
|
|
49
|
-
validation: config.validation,
|
|
50
|
-
metadata: config.metadata,
|
|
51
|
-
tags: config.tags,
|
|
52
52
|
status: config.status || 'active',
|
|
53
|
+
...(config.indexes !== undefined && { indexes: config.indexes }),
|
|
54
|
+
...(config.relationships !== undefined && { relationships: config.relationships }),
|
|
55
|
+
...(config.validation !== undefined && { validation: config.validation }),
|
|
56
|
+
...(config.metadata !== undefined && { metadata: config.metadata }),
|
|
57
|
+
...(config.tags !== undefined && { tags: config.tags }),
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
return registerProduct(data)
|
|
@@ -124,6 +129,6 @@ export function Validate(
|
|
|
124
129
|
field,
|
|
125
130
|
rule,
|
|
126
131
|
params: paramsOrMessage,
|
|
127
|
-
message,
|
|
132
|
+
...(message !== undefined && { message }),
|
|
128
133
|
}
|
|
129
134
|
}
|
package/src/dataset.ts
CHANGED
|
@@ -40,13 +40,13 @@ export function Dataset(config: Omit<DatasetDefinition, 'type'>): DatasetDefinit
|
|
|
40
40
|
version: config.version,
|
|
41
41
|
format: config.format || 'json',
|
|
42
42
|
schema: config.schema,
|
|
43
|
-
source: config.source,
|
|
44
|
-
size: config.size,
|
|
45
|
-
license: config.license,
|
|
46
43
|
updateFrequency: config.updateFrequency || 'static',
|
|
47
|
-
metadata: config.metadata,
|
|
48
|
-
tags: config.tags,
|
|
49
44
|
status: config.status || 'active',
|
|
45
|
+
...(config.source !== undefined && { source: config.source }),
|
|
46
|
+
...(config.size !== undefined && { size: config.size }),
|
|
47
|
+
...(config.license !== undefined && { license: config.license }),
|
|
48
|
+
...(config.metadata !== undefined && { metadata: config.metadata }),
|
|
49
|
+
...(config.tags !== undefined && { tags: config.tags }),
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
return registerProduct(dataset)
|
package/src/index.ts
CHANGED
|
@@ -1,20 +1,115 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* digital-products - Primitives for defining and building digital products
|
|
3
3
|
*
|
|
4
|
-
* This package provides primitives for defining digital products
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
4
|
+
* This package provides primitives for defining digital products using JSON-LD
|
|
5
|
+
* style conventions with `$id` and `$type` fields for schema.org.ai compatibility.
|
|
6
|
+
*
|
|
7
|
+
* ## Product Types
|
|
8
|
+
*
|
|
9
|
+
* - {@link Product} - Base product interface
|
|
10
|
+
* - {@link App} - Interactive user-facing applications (web, mobile, desktop)
|
|
11
|
+
* - {@link API} - Programmatic interfaces with versioning and auth
|
|
12
|
+
* - {@link Site} - Websites (marketing, docs, blog)
|
|
13
|
+
* - {@link Service} - Backend services with endpoints
|
|
14
|
+
* - {@link Feature} - Product features with lifecycle status
|
|
15
|
+
*
|
|
16
|
+
* ## Validation & Type Guards
|
|
17
|
+
*
|
|
18
|
+
* Each product type includes:
|
|
19
|
+
* - Zod schema for runtime validation (e.g., {@link AppSchema})
|
|
20
|
+
* - Type guard function (e.g., {@link isApp})
|
|
21
|
+
* - Factory function with defaults (e.g., {@link createApp})
|
|
22
|
+
*
|
|
23
|
+
* ## Builder Pattern (Legacy)
|
|
24
|
+
*
|
|
25
|
+
* The `*Builder` functions and `*Definition` types are maintained for
|
|
26
|
+
* backwards compatibility. New code should use the unified JSON-LD types.
|
|
13
27
|
*
|
|
14
28
|
* @packageDocumentation
|
|
29
|
+
*
|
|
30
|
+
* @example Creating an App
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { createApp, isApp, AppSchema, App } from 'digital-products'
|
|
33
|
+
*
|
|
34
|
+
* // Using factory function (recommended)
|
|
35
|
+
* const app = createApp({
|
|
36
|
+
* $id: 'https://schema.org.ai/apps/dashboard',
|
|
37
|
+
* name: 'Dashboard',
|
|
38
|
+
* description: 'Admin dashboard application',
|
|
39
|
+
* platform: 'web',
|
|
40
|
+
* url: 'https://dashboard.example.com'
|
|
41
|
+
* })
|
|
42
|
+
* // app.$type === 'https://schema.org.ai/App'
|
|
43
|
+
* // app.status === 'active' (default)
|
|
44
|
+
*
|
|
45
|
+
* // Type guard
|
|
46
|
+
* if (isApp(data)) {
|
|
47
|
+
* console.log(data.platform) // TypeScript knows this is App
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* // Zod validation
|
|
51
|
+
* const result = AppSchema.safeParse(untrustedData)
|
|
52
|
+
* if (result.success) {
|
|
53
|
+
* console.log(result.data.name)
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @example Creating an API
|
|
58
|
+
* ```typescript
|
|
59
|
+
* import { createAPI, API, APISchema } from 'digital-products'
|
|
60
|
+
*
|
|
61
|
+
* const api = createAPI({
|
|
62
|
+
* $id: 'https://schema.org.ai/apis/users',
|
|
63
|
+
* name: 'Users API',
|
|
64
|
+
* description: 'User management REST API',
|
|
65
|
+
* baseUrl: 'https://api.example.com/v1',
|
|
66
|
+
* version: '1.0.0',
|
|
67
|
+
* authentication: 'bearer'
|
|
68
|
+
* })
|
|
69
|
+
* // api.$type === 'https://schema.org.ai/API'
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @example Creating a Site
|
|
73
|
+
* ```typescript
|
|
74
|
+
* import { createSite, Site, SiteSchema } from 'digital-products'
|
|
75
|
+
*
|
|
76
|
+
* const site = createSite({
|
|
77
|
+
* $id: 'https://schema.org.ai/sites/docs',
|
|
78
|
+
* name: 'Documentation',
|
|
79
|
+
* description: 'Product documentation site',
|
|
80
|
+
* url: 'https://docs.example.com',
|
|
81
|
+
* siteType: 'docs'
|
|
82
|
+
* })
|
|
83
|
+
* // site.$type === 'https://schema.org.ai/Site'
|
|
84
|
+
* ```
|
|
15
85
|
*/
|
|
16
86
|
|
|
17
|
-
//
|
|
87
|
+
// =============================================================================
|
|
88
|
+
// UNIFIED TYPES (JSON-LD Style) - Recommended
|
|
89
|
+
// =============================================================================
|
|
90
|
+
//
|
|
91
|
+
// These exports from types.ts include:
|
|
92
|
+
//
|
|
93
|
+
// INTERFACES (JSON-LD style with $id/$type):
|
|
94
|
+
// - Product - Base product interface
|
|
95
|
+
// - App - Application (web, mobile, desktop)
|
|
96
|
+
// - API - API with versioning and authentication
|
|
97
|
+
// - Site - Website (marketing, docs, blog)
|
|
98
|
+
// - Service - Backend service with endpoints
|
|
99
|
+
// - Feature - Product feature with lifecycle
|
|
100
|
+
//
|
|
101
|
+
// ZOD SCHEMAS (runtime validation):
|
|
102
|
+
// - ProductSchema, AppSchema, APISchema, SiteSchema, ServiceSchema, FeatureSchema
|
|
103
|
+
//
|
|
104
|
+
// TYPE GUARDS:
|
|
105
|
+
// - isProduct, isApp, isAPI, isSite, isService, isFeature
|
|
106
|
+
//
|
|
107
|
+
// FACTORY FUNCTIONS (with sensible defaults):
|
|
108
|
+
// - createProduct, createApp, createAPI, createSite, createService, createFeature
|
|
109
|
+
//
|
|
110
|
+
// LEGACY TYPES (for backwards compatibility):
|
|
111
|
+
// - DigitalProduct, AppDefinition, APIDefinition, SiteDefinition, etc.
|
|
112
|
+
//
|
|
18
113
|
export * from './types.js'
|
|
19
114
|
|
|
20
115
|
// Export entity definitions (Nouns) as namespace to avoid conflicts with types
|
|
@@ -43,13 +138,54 @@ export {
|
|
|
43
138
|
// Export registry
|
|
44
139
|
export { registry } from './registry.js'
|
|
45
140
|
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
141
|
+
// =============================================================================
|
|
142
|
+
// BUILDER PATTERN (Legacy API)
|
|
143
|
+
// =============================================================================
|
|
144
|
+
//
|
|
145
|
+
// These builder functions create *Definition types (e.g., AppDefinition),
|
|
146
|
+
// which use `id` and `type` fields instead of JSON-LD `$id`/`$type`.
|
|
147
|
+
//
|
|
148
|
+
// For new code, prefer the unified types above:
|
|
149
|
+
// - createApp() creates App with $id/$type (JSON-LD)
|
|
150
|
+
// - AppBuilder() creates AppDefinition with id/type (legacy)
|
|
151
|
+
//
|
|
152
|
+
// The *Builder exports are renamed to avoid conflicts with the type interfaces.
|
|
153
|
+
// The original function names (App, API, Site) are also exported for backwards
|
|
154
|
+
// compatibility - TypeScript allows functions and types to share the same name.
|
|
155
|
+
//
|
|
156
|
+
|
|
157
|
+
/** @deprecated Use createProduct() from unified types instead */
|
|
158
|
+
export {
|
|
159
|
+
Product as ProductBuilder,
|
|
160
|
+
createProduct as createProductDefinition,
|
|
161
|
+
registerProduct,
|
|
162
|
+
} from './product.js'
|
|
163
|
+
|
|
164
|
+
/** @deprecated Use createApp() from unified types instead */
|
|
165
|
+
export { App as AppBuilder, Route, State, Auth } from './app.js'
|
|
166
|
+
|
|
167
|
+
/** @deprecated Use createAPI() from unified types instead */
|
|
168
|
+
export { API as APIBuilder, Endpoint, APIAuth, RateLimit } from './api.js'
|
|
169
|
+
|
|
50
170
|
export { Content, Workflow } from './content.js'
|
|
51
171
|
export { Data, Index, Relationship, Validate } from './data.js'
|
|
52
172
|
export { Dataset } from './dataset.js'
|
|
53
|
-
|
|
173
|
+
|
|
174
|
+
/** @deprecated Use createSite() from unified types instead */
|
|
175
|
+
export { Site as SiteBuilder, Nav, SEO, Analytics } from './site.js'
|
|
176
|
+
|
|
54
177
|
export { MCP, Tool, Resource, Prompt, MCPConfig } from './mcp.js'
|
|
55
178
|
export { SDK, Export, Example } from './sdk.js'
|
|
179
|
+
|
|
180
|
+
// Re-export builder functions under original names for backwards compatibility.
|
|
181
|
+
// This allows: import { Site } from 'digital-products'; Site({...}) // builder
|
|
182
|
+
// While also: import type { Site } from 'digital-products'; const x: Site = {...} // type
|
|
183
|
+
// TypeScript allows function and type/interface with same name.
|
|
184
|
+
import { Product as ProductFn } from './product.js'
|
|
185
|
+
import { App as AppFn } from './app.js'
|
|
186
|
+
import { API as APIFn } from './api.js'
|
|
187
|
+
import { Site as SiteFn } from './site.js'
|
|
188
|
+
|
|
189
|
+
// Export builder functions - these shadow the type exports at runtime
|
|
190
|
+
// (which is fine since TypeScript types are erased at compile time)
|
|
191
|
+
export { ProductFn as Product, AppFn as App, APIFn as API, SiteFn as Site }
|
package/src/mcp.ts
CHANGED
|
@@ -44,13 +44,13 @@ export function MCP(config: Omit<MCPDefinition, 'type'>): MCPDefinition {
|
|
|
44
44
|
description: config.description,
|
|
45
45
|
version: config.version,
|
|
46
46
|
transport: config.transport,
|
|
47
|
-
tools: config.tools,
|
|
48
|
-
resources: config.resources,
|
|
49
|
-
prompts: config.prompts,
|
|
50
|
-
config: config.config,
|
|
51
|
-
metadata: config.metadata,
|
|
52
|
-
tags: config.tags,
|
|
53
47
|
status: config.status || 'active',
|
|
48
|
+
...(config.tools !== undefined && { tools: config.tools }),
|
|
49
|
+
...(config.resources !== undefined && { resources: config.resources }),
|
|
50
|
+
...(config.prompts !== undefined && { prompts: config.prompts }),
|
|
51
|
+
...(config.config !== undefined && { config: config.config }),
|
|
52
|
+
...(config.metadata !== undefined && { metadata: config.metadata }),
|
|
53
|
+
...(config.tags !== undefined && { tags: config.tags }),
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
return registerProduct(mcp)
|
|
@@ -78,14 +78,14 @@ export function MCP(config: Omit<MCPDefinition, 'type'>): MCPDefinition {
|
|
|
78
78
|
export function Tool(
|
|
79
79
|
name: string,
|
|
80
80
|
description: string,
|
|
81
|
-
inputSchema:
|
|
81
|
+
inputSchema: Record<string, unknown>,
|
|
82
82
|
handler?: (input: unknown) => Promise<unknown>
|
|
83
83
|
): MCPTool {
|
|
84
84
|
return {
|
|
85
85
|
name,
|
|
86
86
|
description,
|
|
87
|
-
inputSchema,
|
|
88
|
-
handler,
|
|
87
|
+
inputSchema: inputSchema as MCPTool['inputSchema'],
|
|
88
|
+
...(handler !== undefined && { handler }),
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -112,7 +112,7 @@ export function Resource(
|
|
|
112
112
|
uri,
|
|
113
113
|
name,
|
|
114
114
|
description,
|
|
115
|
-
mimeType,
|
|
115
|
+
...(mimeType !== undefined && { mimeType }),
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -135,11 +135,18 @@ export function Prompt(
|
|
|
135
135
|
template: string,
|
|
136
136
|
args?: SimpleSchema
|
|
137
137
|
): MCPPrompt {
|
|
138
|
+
if (args !== undefined) {
|
|
139
|
+
return {
|
|
140
|
+
name,
|
|
141
|
+
description,
|
|
142
|
+
template,
|
|
143
|
+
arguments: args as Record<string, unknown>,
|
|
144
|
+
}
|
|
145
|
+
}
|
|
138
146
|
return {
|
|
139
147
|
name,
|
|
140
148
|
description,
|
|
141
149
|
template,
|
|
142
|
-
arguments: args,
|
|
143
150
|
}
|
|
144
151
|
}
|
|
145
152
|
|
package/src/product.ts
CHANGED
|
@@ -24,9 +24,9 @@ export function Product(config: Omit<DigitalProduct, 'type'>): DigitalProduct {
|
|
|
24
24
|
name: config.name,
|
|
25
25
|
description: config.description,
|
|
26
26
|
version: config.version,
|
|
27
|
-
metadata: config.metadata,
|
|
28
|
-
tags: config.tags,
|
|
29
27
|
status: config.status || 'active',
|
|
28
|
+
...(config.metadata !== undefined && { metadata: config.metadata }),
|
|
29
|
+
...(config.tags !== undefined && { tags: config.tags }),
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
return product
|
package/src/sdk.ts
CHANGED
|
@@ -62,14 +62,14 @@ export function SDK(config: Omit<SDKDefinition, 'type'>): SDKDefinition {
|
|
|
62
62
|
description: config.description,
|
|
63
63
|
version: config.version,
|
|
64
64
|
language: config.language,
|
|
65
|
-
api: config.api,
|
|
66
|
-
exports: config.exports,
|
|
67
|
-
install: config.install,
|
|
68
|
-
docs: config.docs,
|
|
69
|
-
examples: config.examples,
|
|
70
|
-
metadata: config.metadata,
|
|
71
|
-
tags: config.tags,
|
|
72
65
|
status: config.status || 'active',
|
|
66
|
+
...(config.api !== undefined && { api: config.api }),
|
|
67
|
+
...(config.exports !== undefined && { exports: config.exports }),
|
|
68
|
+
...(config.install !== undefined && { install: config.install }),
|
|
69
|
+
...(config.docs !== undefined && { docs: config.docs }),
|
|
70
|
+
...(config.examples !== undefined && { examples: config.examples }),
|
|
71
|
+
...(config.metadata !== undefined && { metadata: config.metadata }),
|
|
72
|
+
...(config.tags !== undefined && { tags: config.tags }),
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
return registerProduct(sdk)
|
|
@@ -108,14 +108,53 @@ export function Export(
|
|
|
108
108
|
methods?: SDKExport[]
|
|
109
109
|
}
|
|
110
110
|
): SDKExport {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
const base = { type, name, description }
|
|
112
|
+
|
|
113
|
+
// Build the result object conditionally to satisfy exactOptionalPropertyTypes
|
|
114
|
+
// Cast to Record<string, unknown> to match the local SimpleSchema type
|
|
115
|
+
if (
|
|
116
|
+
options?.parameters !== undefined &&
|
|
117
|
+
options?.returns !== undefined &&
|
|
118
|
+
options?.methods !== undefined
|
|
119
|
+
) {
|
|
120
|
+
return {
|
|
121
|
+
...base,
|
|
122
|
+
parameters: options.parameters as Record<string, unknown>,
|
|
123
|
+
returns: options.returns as Record<string, unknown>,
|
|
124
|
+
methods: options.methods,
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (options?.parameters !== undefined && options?.returns !== undefined) {
|
|
128
|
+
return {
|
|
129
|
+
...base,
|
|
130
|
+
parameters: options.parameters as Record<string, unknown>,
|
|
131
|
+
returns: options.returns as Record<string, unknown>,
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (options?.parameters !== undefined && options?.methods !== undefined) {
|
|
135
|
+
return {
|
|
136
|
+
...base,
|
|
137
|
+
parameters: options.parameters as Record<string, unknown>,
|
|
138
|
+
methods: options.methods,
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (options?.returns !== undefined && options?.methods !== undefined) {
|
|
142
|
+
return {
|
|
143
|
+
...base,
|
|
144
|
+
returns: options.returns as Record<string, unknown>,
|
|
145
|
+
methods: options.methods,
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (options?.parameters !== undefined) {
|
|
149
|
+
return { ...base, parameters: options.parameters as Record<string, unknown> }
|
|
150
|
+
}
|
|
151
|
+
if (options?.returns !== undefined) {
|
|
152
|
+
return { ...base, returns: options.returns as Record<string, unknown> }
|
|
153
|
+
}
|
|
154
|
+
if (options?.methods !== undefined) {
|
|
155
|
+
return { ...base, methods: options.methods }
|
|
118
156
|
}
|
|
157
|
+
return base
|
|
119
158
|
}
|
|
120
159
|
|
|
121
160
|
/**
|
|
@@ -143,6 +182,6 @@ export function Example(
|
|
|
143
182
|
title,
|
|
144
183
|
description,
|
|
145
184
|
code,
|
|
146
|
-
output,
|
|
185
|
+
...(output !== undefined && { output }),
|
|
147
186
|
}
|
|
148
187
|
}
|
package/src/site.ts
CHANGED
|
@@ -52,14 +52,14 @@ export function Site(config: Omit<SiteDefinition, 'type'>): SiteDefinition {
|
|
|
52
52
|
description: config.description,
|
|
53
53
|
version: config.version,
|
|
54
54
|
generator: config.generator || 'next',
|
|
55
|
-
structure: config.structure,
|
|
56
|
-
navigation: config.navigation,
|
|
57
|
-
seo: config.seo,
|
|
58
|
-
analytics: config.analytics,
|
|
59
|
-
deployment: config.deployment,
|
|
60
|
-
metadata: config.metadata,
|
|
61
|
-
tags: config.tags,
|
|
62
55
|
status: config.status || 'active',
|
|
56
|
+
...(config.structure !== undefined && { structure: config.structure }),
|
|
57
|
+
...(config.navigation !== undefined && { navigation: config.navigation }),
|
|
58
|
+
...(config.seo !== undefined && { seo: config.seo }),
|
|
59
|
+
...(config.analytics !== undefined && { analytics: config.analytics }),
|
|
60
|
+
...(config.deployment !== undefined && { deployment: config.deployment }),
|
|
61
|
+
...(config.metadata !== undefined && { metadata: config.metadata }),
|
|
62
|
+
...(config.tags !== undefined && { tags: config.tags }),
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
return registerProduct(site)
|
|
@@ -123,5 +123,9 @@ export function Analytics(
|
|
|
123
123
|
id: string,
|
|
124
124
|
config?: Record<string, unknown>
|
|
125
125
|
): AnalyticsConfig {
|
|
126
|
-
return {
|
|
126
|
+
return {
|
|
127
|
+
provider,
|
|
128
|
+
id,
|
|
129
|
+
...(config !== undefined && { config }),
|
|
130
|
+
}
|
|
127
131
|
}
|