services-as-software 0.1.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/CHANGELOG.md +10 -0
  3. package/README.md +235 -225
  4. package/dist/client.d.ts +25 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +103 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/endpoint.d.ts +102 -0
  9. package/dist/endpoint.d.ts.map +1 -0
  10. package/dist/endpoint.js +96 -0
  11. package/dist/endpoint.js.map +1 -0
  12. package/dist/entities/billing.d.ts +60 -0
  13. package/dist/entities/billing.d.ts.map +1 -0
  14. package/dist/entities/billing.js +954 -0
  15. package/dist/entities/billing.js.map +1 -0
  16. package/dist/entities/customers.d.ts +45 -0
  17. package/dist/entities/customers.d.ts.map +1 -0
  18. package/dist/entities/customers.js +679 -0
  19. package/dist/entities/customers.js.map +1 -0
  20. package/dist/entities/delivery.d.ts +59 -0
  21. package/dist/entities/delivery.d.ts.map +1 -0
  22. package/dist/entities/delivery.js +890 -0
  23. package/dist/entities/delivery.js.map +1 -0
  24. package/dist/entities/index.d.ts +114 -0
  25. package/dist/entities/index.d.ts.map +1 -0
  26. package/dist/entities/index.js +89 -0
  27. package/dist/entities/index.js.map +1 -0
  28. package/dist/entities/operations.d.ts +59 -0
  29. package/dist/entities/operations.d.ts.map +1 -0
  30. package/dist/entities/operations.js +1010 -0
  31. package/dist/entities/operations.js.map +1 -0
  32. package/dist/entities/orchestration.d.ts +52 -0
  33. package/dist/entities/orchestration.d.ts.map +1 -0
  34. package/dist/entities/orchestration.js +883 -0
  35. package/dist/entities/orchestration.js.map +1 -0
  36. package/dist/entities/services.d.ts +50 -0
  37. package/dist/entities/services.d.ts.map +1 -0
  38. package/dist/entities/services.js +805 -0
  39. package/dist/entities/services.js.map +1 -0
  40. package/dist/helpers.d.ts +362 -0
  41. package/dist/helpers.d.ts.map +1 -0
  42. package/dist/helpers.js +400 -0
  43. package/dist/helpers.js.map +1 -0
  44. package/dist/index.d.ts +17 -215
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +18 -172
  47. package/dist/index.js.map +1 -0
  48. package/dist/provider.d.ts +85 -0
  49. package/dist/provider.d.ts.map +1 -0
  50. package/dist/provider.js +158 -0
  51. package/dist/provider.js.map +1 -0
  52. package/dist/service.d.ts +43 -0
  53. package/dist/service.d.ts.map +1 -0
  54. package/dist/service.js +206 -0
  55. package/dist/service.js.map +1 -0
  56. package/dist/types.d.ts +469 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +5 -0
  59. package/dist/types.js.map +1 -0
  60. package/examples/client-usage.ts +82 -0
  61. package/examples/translation-service.ts +227 -0
  62. package/package.json +24 -38
  63. package/src/client.ts +132 -0
  64. package/src/endpoint.ts +144 -0
  65. package/src/entities/billing.ts +1037 -0
  66. package/src/entities/customers.ts +740 -0
  67. package/src/entities/delivery.ts +974 -0
  68. package/src/entities/index.ts +157 -0
  69. package/src/entities/operations.ts +1099 -0
  70. package/src/entities/orchestration.ts +956 -0
  71. package/src/entities/services.ts +872 -0
  72. package/src/helpers.ts +474 -0
  73. package/src/index.ts +97 -0
  74. package/src/provider.ts +183 -0
  75. package/src/service.test.ts +195 -0
  76. package/src/service.ts +266 -0
  77. package/src/types.ts +543 -0
  78. package/tsconfig.json +9 -0
package/src/helpers.ts ADDED
@@ -0,0 +1,474 @@
1
+ /**
2
+ * Helper functions for common service operations
3
+ */
4
+
5
+ import type {
6
+ Notification,
7
+ Order,
8
+ Quote,
9
+ Subscription,
10
+ OKRDefinition,
11
+ KPIDefinition,
12
+ EntitlementDefinition,
13
+ SubscriptionPlan,
14
+ ServiceContext,
15
+ JSONSchema,
16
+ } from './types.js'
17
+
18
+ /**
19
+ * Ask a question (helper for creating ask endpoints)
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const askEndpoint = Endpoint({
24
+ * name: 'ask',
25
+ * handler: ask(async (question, context) => {
26
+ * // Your Q&A logic here
27
+ * return `Answer to: ${question}`
28
+ * }),
29
+ * })
30
+ * ```
31
+ */
32
+ export function ask(
33
+ handler: (question: string, context?: unknown, serviceContext?: ServiceContext) => Promise<string>
34
+ ) {
35
+ return async (
36
+ input: { question: string; context?: unknown },
37
+ serviceContext?: ServiceContext
38
+ ): Promise<string> => {
39
+ return handler(input.question, input.context, serviceContext)
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Deliver results (helper for creating deliver endpoints)
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * const deliverEndpoint = Endpoint({
49
+ * name: 'deliver',
50
+ * handler: deliver(async (orderId, results) => {
51
+ * // Delivery logic here
52
+ * console.log(`Delivering order ${orderId}`)
53
+ * }),
54
+ * })
55
+ * ```
56
+ */
57
+ export function deliver(
58
+ handler: (orderId: string, results: unknown, context?: ServiceContext) => Promise<void>
59
+ ) {
60
+ return async (
61
+ input: { orderId: string; results: unknown },
62
+ context?: ServiceContext
63
+ ): Promise<void> => {
64
+ return handler(input.orderId, input.results, context)
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Execute a task (helper for creating do endpoints)
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * const doEndpoint = Endpoint({
74
+ * name: 'do',
75
+ * handler: do(async (action, input) => {
76
+ * switch (action) {
77
+ * case 'process':
78
+ * return { status: 'processed' }
79
+ * default:
80
+ * throw new Error(`Unknown action: ${action}`)
81
+ * }
82
+ * }),
83
+ * })
84
+ * ```
85
+ */
86
+ export function do_(
87
+ handler: (action: string, input?: unknown, context?: ServiceContext) => Promise<unknown>
88
+ ) {
89
+ return async (
90
+ input: { action: string; input?: unknown },
91
+ context?: ServiceContext
92
+ ): Promise<unknown> => {
93
+ return handler(input.action, input.input, context)
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Generate content (helper for creating generate endpoints)
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const generateEndpoint = Endpoint({
103
+ * name: 'generate',
104
+ * handler: generate(async (prompt, options) => {
105
+ * // Generation logic here
106
+ * return { text: `Generated from: ${prompt}` }
107
+ * }),
108
+ * })
109
+ * ```
110
+ */
111
+ export function generate(
112
+ handler: (prompt: string, options?: unknown, context?: ServiceContext) => Promise<unknown>
113
+ ) {
114
+ return async (
115
+ input: { prompt: string; options?: unknown },
116
+ context?: ServiceContext
117
+ ): Promise<unknown> => {
118
+ return handler(input.prompt, input.options, context)
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Type checking/validation (helper for creating is endpoints)
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * const isEndpoint = Endpoint({
128
+ * name: 'is',
129
+ * handler: is(async (value, type) => {
130
+ * // Validation logic here
131
+ * return typeof value === type
132
+ * }),
133
+ * })
134
+ * ```
135
+ */
136
+ export function is(
137
+ handler: (value: unknown, type: string | JSONSchema, context?: ServiceContext) => Promise<boolean>
138
+ ) {
139
+ return async (
140
+ input: { value: unknown; type: string | JSONSchema },
141
+ context?: ServiceContext
142
+ ): Promise<boolean> => {
143
+ return handler(input.value, input.type, context)
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Send notification (helper for creating notify endpoints)
149
+ *
150
+ * @example
151
+ * ```ts
152
+ * const notifyEndpoint = Endpoint({
153
+ * name: 'notify',
154
+ * handler: notify(async (notification) => {
155
+ * // Send notification via email, Slack, etc.
156
+ * console.log(`Sending notification: ${notification.subject}`)
157
+ * }),
158
+ * })
159
+ * ```
160
+ */
161
+ export function notify(
162
+ handler: (notification: Notification, context?: ServiceContext) => Promise<void>
163
+ ) {
164
+ return async (input: Notification, context?: ServiceContext): Promise<void> => {
165
+ return handler(input, context)
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Event handler (helper for creating event handlers)
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * service.on('order.created', on(async (order) => {
175
+ * console.log(`New order: ${order.id}`)
176
+ * }))
177
+ * ```
178
+ */
179
+ export function on<TPayload>(
180
+ handler: (payload: TPayload, context?: ServiceContext) => void | Promise<void>
181
+ ) {
182
+ return handler
183
+ }
184
+
185
+ /**
186
+ * Place an order (helper for creating order endpoints)
187
+ *
188
+ * @example
189
+ * ```ts
190
+ * const orderEndpoint = Endpoint({
191
+ * name: 'order',
192
+ * handler: order(async (product, quantity, context) => {
193
+ * const orderId = generateOrderId()
194
+ * return {
195
+ * id: orderId,
196
+ * customerId: context?.customerId || 'unknown',
197
+ * product,
198
+ * quantity,
199
+ * total: calculateTotal(product, quantity),
200
+ * currency: 'USD',
201
+ * status: 'pending',
202
+ * createdAt: new Date(),
203
+ * updatedAt: new Date(),
204
+ * }
205
+ * }),
206
+ * })
207
+ * ```
208
+ */
209
+ export function order<TProduct>(
210
+ handler: (product: TProduct, quantity: number, context?: ServiceContext) => Promise<Order<TProduct>>
211
+ ) {
212
+ return async (
213
+ input: { product: TProduct; quantity: number },
214
+ context?: ServiceContext
215
+ ): Promise<Order<TProduct>> => {
216
+ return handler(input.product, input.quantity, context)
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Queue processor (helper for queue handlers)
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * service.queue('process-orders', queue(async (job) => {
226
+ * console.log(`Processing job: ${job.id}`)
227
+ * }))
228
+ * ```
229
+ */
230
+ export function queue<TJob>(
231
+ handler: (job: TJob, context?: ServiceContext) => void | Promise<void>
232
+ ) {
233
+ return handler
234
+ }
235
+
236
+ /**
237
+ * Request a quote (helper for creating quote endpoints)
238
+ *
239
+ * @example
240
+ * ```ts
241
+ * const quoteEndpoint = Endpoint({
242
+ * name: 'quote',
243
+ * handler: quote(async (product, quantity, context) => {
244
+ * const price = calculatePrice(product, quantity)
245
+ * return {
246
+ * id: generateQuoteId(),
247
+ * customerId: context?.customerId || 'unknown',
248
+ * product,
249
+ * quantity,
250
+ * price,
251
+ * currency: 'USD',
252
+ * expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
253
+ * }
254
+ * }),
255
+ * })
256
+ * ```
257
+ */
258
+ export function quote<TProduct>(
259
+ handler: (product: TProduct, quantity: number, context?: ServiceContext) => Promise<Quote<TProduct>>
260
+ ) {
261
+ return async (
262
+ input: { product: TProduct; quantity: number },
263
+ context?: ServiceContext
264
+ ): Promise<Quote<TProduct>> => {
265
+ return handler(input.product, input.quantity, context)
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Subscribe to a plan (helper for creating subscribe endpoints)
271
+ *
272
+ * @example
273
+ * ```ts
274
+ * const subscribeEndpoint = Endpoint({
275
+ * name: 'subscribe',
276
+ * handler: subscribe(async (planId, context) => {
277
+ * const plan = findPlan(planId)
278
+ * return {
279
+ * id: generateSubscriptionId(),
280
+ * customerId: context?.customerId || 'unknown',
281
+ * planId,
282
+ * status: 'active',
283
+ * currentPeriodStart: new Date(),
284
+ * currentPeriodEnd: getNextBillingDate(plan.pricing.interval),
285
+ * }
286
+ * }),
287
+ * })
288
+ * ```
289
+ */
290
+ export function subscribe(
291
+ handler: (planId: string, context?: ServiceContext) => Promise<Subscription>
292
+ ) {
293
+ return async (input: { planId: string }, context?: ServiceContext): Promise<Subscription> => {
294
+ return handler(input.planId, context)
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Scheduled task (helper for every/scheduled tasks)
300
+ *
301
+ * @example
302
+ * ```ts
303
+ * service.every('0 0 * * *', every(async () => {
304
+ * console.log('Running daily task')
305
+ * }))
306
+ * ```
307
+ */
308
+ export function every(handler: (context?: ServiceContext) => void | Promise<void>) {
309
+ return handler
310
+ }
311
+
312
+ /**
313
+ * Get entitlements (helper for creating entitlements endpoints)
314
+ *
315
+ * @example
316
+ * ```ts
317
+ * const entitlementsEndpoint = Endpoint({
318
+ * name: 'entitlements',
319
+ * handler: entitlements(async (context) => {
320
+ * return context?.entitlements || []
321
+ * }),
322
+ * })
323
+ * ```
324
+ */
325
+ export function entitlements(handler: (context?: ServiceContext) => Promise<string[]>) {
326
+ return async (_input: unknown, context?: ServiceContext): Promise<string[]> => {
327
+ return handler(context)
328
+ }
329
+ }
330
+
331
+ /**
332
+ * Get KPIs (helper for creating KPI endpoints)
333
+ *
334
+ * @example
335
+ * ```ts
336
+ * const kpisEndpoint = Endpoint({
337
+ * name: 'kpis',
338
+ * handler: kpis(async () => {
339
+ * return {
340
+ * 'revenue': 10000,
341
+ * 'customers': 150,
342
+ * 'satisfaction': 4.5,
343
+ * }
344
+ * }),
345
+ * })
346
+ * ```
347
+ */
348
+ export function kpis(handler: (context?: ServiceContext) => Promise<Record<string, number | string>>) {
349
+ return async (_input: unknown, context?: ServiceContext): Promise<Record<string, number | string>> => {
350
+ return handler(context)
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Get OKRs (helper for creating OKR endpoints)
356
+ *
357
+ * @example
358
+ * ```ts
359
+ * const okrsEndpoint = Endpoint({
360
+ * name: 'okrs',
361
+ * handler: okrs(async () => {
362
+ * return [{
363
+ * id: 'okr-1',
364
+ * objective: 'Improve customer satisfaction',
365
+ * keyResults: [
366
+ * {
367
+ * description: 'Increase NPS score',
368
+ * measure: async () => 8.5,
369
+ * target: 9.0,
370
+ * unit: 'score',
371
+ * },
372
+ * ],
373
+ * }]
374
+ * }),
375
+ * })
376
+ * ```
377
+ */
378
+ export function okrs(handler: (context?: ServiceContext) => Promise<OKRDefinition[]>) {
379
+ return async (_input: unknown, context?: ServiceContext): Promise<OKRDefinition[]> => {
380
+ return handler(context)
381
+ }
382
+ }
383
+
384
+ /**
385
+ * Create a subscription plan
386
+ *
387
+ * @example
388
+ * ```ts
389
+ * const plan = Plan({
390
+ * id: 'pro',
391
+ * name: 'Pro Plan',
392
+ * description: 'For professional users',
393
+ * pricing: {
394
+ * model: 'subscription',
395
+ * basePrice: 49.99,
396
+ * currency: 'USD',
397
+ * interval: 'monthly',
398
+ * },
399
+ * entitlements: ['api-access', 'advanced-features'],
400
+ * features: ['Unlimited API calls', '24/7 support', 'Custom integrations'],
401
+ * limits: {
402
+ * 'api-calls': 100000,
403
+ * 'storage': 1000000000, // 1GB in bytes
404
+ * },
405
+ * })
406
+ * ```
407
+ */
408
+ export function Plan(plan: SubscriptionPlan): SubscriptionPlan {
409
+ return plan
410
+ }
411
+
412
+ /**
413
+ * Create a KPI definition
414
+ *
415
+ * @example
416
+ * ```ts
417
+ * const kpi = KPI({
418
+ * id: 'monthly-revenue',
419
+ * name: 'Monthly Revenue',
420
+ * description: 'Total revenue for the current month',
421
+ * calculate: async () => {
422
+ * return await getMonthlyRevenue()
423
+ * },
424
+ * target: 100000,
425
+ * unit: 'USD',
426
+ * })
427
+ * ```
428
+ */
429
+ export function KPI(kpi: KPIDefinition): KPIDefinition {
430
+ return kpi
431
+ }
432
+
433
+ /**
434
+ * Create an OKR definition
435
+ *
436
+ * @example
437
+ * ```ts
438
+ * const okr = OKR({
439
+ * id: 'q1-2024',
440
+ * objective: 'Grow user base by 50%',
441
+ * keyResults: [
442
+ * {
443
+ * description: 'Acquire 5000 new users',
444
+ * measure: async () => await getNewUserCount(),
445
+ * target: 5000,
446
+ * unit: 'users',
447
+ * },
448
+ * ],
449
+ * period: 'Q1 2024',
450
+ * owner: 'Growth Team',
451
+ * })
452
+ * ```
453
+ */
454
+ export function OKR(okr: OKRDefinition): OKRDefinition {
455
+ return okr
456
+ }
457
+
458
+ /**
459
+ * Create an entitlement definition
460
+ *
461
+ * @example
462
+ * ```ts
463
+ * const entitlement = Entitlement({
464
+ * id: 'api-access',
465
+ * name: 'API Access',
466
+ * description: 'Access to the service API',
467
+ * resource: 'api',
468
+ * actions: ['read', 'write'],
469
+ * })
470
+ * ```
471
+ */
472
+ export function Entitlement(entitlement: EntitlementDefinition): EntitlementDefinition {
473
+ return entitlement
474
+ }
package/src/index.ts ADDED
@@ -0,0 +1,97 @@
1
+ /**
2
+ * services-as-software - Primitives for building AI-powered services that operate as software
3
+ *
4
+ * Services are a superset of digital-workers with a payment/business overlay,
5
+ * capable of crossing company/business boundaries.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+
10
+ // Export entity definitions (Nouns)
11
+ export * from './entities/index.js'
12
+
13
+ // Core service primitives
14
+ export { Service } from './service.js'
15
+ export { Endpoint, GET, POST, PUT, DELETE, PATCH } from './endpoint.js'
16
+ export { Client } from './client.js'
17
+ export { Provider, providers } from './provider.js'
18
+
19
+ // Helper functions for common operations
20
+ export {
21
+ ask,
22
+ deliver,
23
+ do_ as do,
24
+ generate,
25
+ is,
26
+ notify,
27
+ on,
28
+ order,
29
+ queue,
30
+ quote,
31
+ subscribe,
32
+ every,
33
+ entitlements,
34
+ kpis,
35
+ okrs,
36
+ Plan,
37
+ KPI,
38
+ OKR,
39
+ Entitlement,
40
+ } from './helpers.js'
41
+
42
+ // Export all types
43
+ export type {
44
+ // Core types
45
+ Service as ServiceType,
46
+ ServiceDefinition,
47
+ ServiceClient,
48
+ ServiceContext,
49
+ ServiceStatus,
50
+
51
+ // Endpoint types
52
+ EndpointDefinition,
53
+
54
+ // Pricing types
55
+ PricingModel,
56
+ PricingConfig,
57
+ PricingTier,
58
+ BillingInterval,
59
+ Currency,
60
+
61
+ // Order/Quote/Subscription types
62
+ Order,
63
+ OrderStatus,
64
+ Quote,
65
+ Subscription,
66
+ SubscriptionStatus,
67
+ SubscriptionPlan,
68
+
69
+ // Notification types
70
+ Notification,
71
+
72
+ // Event/Task types
73
+ EventHandler,
74
+ ScheduledTask,
75
+
76
+ // Entitlement/KPI/OKR types
77
+ EntitlementDefinition,
78
+ KPIDefinition,
79
+ OKRDefinition,
80
+ KeyResult,
81
+
82
+ // Usage tracking types
83
+ UsageTracker,
84
+ UsageEvent,
85
+ Usage,
86
+
87
+ // Client/Provider types
88
+ ClientConfig,
89
+ Provider as ProviderType,
90
+
91
+ // Re-export useful types from ai-functions
92
+ JSONSchema,
93
+ } from './types.js'
94
+
95
+ // Re-export endpoint config type
96
+ export type { EndpointConfig } from './endpoint.js'
97
+ export type { ProviderConfig } from './provider.js'