@farthershore/product 0.0.0 → 0.1.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/README.md +140 -0
- package/dist/bin.js +404 -63
- package/dist/codegen.js +23 -0
- package/dist/index.js +404 -63
- package/dist/types/business.d.ts +28 -9
- package/dist/types/index.d.ts +2 -1
- package/dist/types/ir-types.d.ts +25 -0
- package/dist/types/resource-graph.d.ts +36 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# @farthershore/product
|
|
2
|
+
|
|
3
|
+
Product-as-Code SDK for Farther Shore. Builder repos use this package in
|
|
4
|
+
`product.config.ts` to declare product contracts in TypeScript. Builders author
|
|
5
|
+
and export a `Business`; the Farther Shore GitHub bot checks and publishes those
|
|
6
|
+
declarations when repo changes land.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pnpm add @farthershore/product
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Builder repos generated by Farther Shore already pin this dependency in
|
|
15
|
+
`package.json`.
|
|
16
|
+
|
|
17
|
+
## Example
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { fs } from "@farthershore/product";
|
|
21
|
+
|
|
22
|
+
const business = fs.business("croncloud", {
|
|
23
|
+
baseUrl: "https://api.example.com",
|
|
24
|
+
displayName: "CronCloud",
|
|
25
|
+
description: "Managed cron jobs",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
business.meter("requests", { display: "Requests" });
|
|
29
|
+
|
|
30
|
+
business.resource("cron_jobs", {
|
|
31
|
+
display: "Cron jobs",
|
|
32
|
+
countSource: "action_inferred",
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const cron = business.capability("managed-cron", {
|
|
36
|
+
title: "Managed Cron Jobs",
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const jobs = business.feature("cron-jobs", {
|
|
40
|
+
description: "Cron job CRUD",
|
|
41
|
+
capabilities: [cron],
|
|
42
|
+
routes: [{ match: "GET /v1/cron-jobs", meters: ["requests"] }],
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const createJob = jobs.action("cron-job.create", {
|
|
46
|
+
kind: "mutation",
|
|
47
|
+
title: "Create cron job",
|
|
48
|
+
resource: { resource: "cron_jobs", effect: "create" },
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
jobs.route("POST /v1/cron-jobs", {
|
|
52
|
+
meters: ["requests"],
|
|
53
|
+
action: createJob,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
business.plan("starter", {
|
|
57
|
+
name: "Starter",
|
|
58
|
+
price: fs.price.monthly(29),
|
|
59
|
+
grants: [cron.enable({ limits: { cron_jobs: 10 } })],
|
|
60
|
+
limits: [
|
|
61
|
+
{
|
|
62
|
+
dimension: "requests",
|
|
63
|
+
window: { type: "named", name: "minute" },
|
|
64
|
+
capacity: 600,
|
|
65
|
+
enforcement: "enforce",
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export default business;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Bot build
|
|
74
|
+
|
|
75
|
+
Normal product repos do not call platform release or IR APIs. The GitHub bot
|
|
76
|
+
owns that workflow:
|
|
77
|
+
|
|
78
|
+
1. Loads `product.config.ts`.
|
|
79
|
+
2. Requires the default export to be the `Business` returned by
|
|
80
|
+
`fs.business(...)` or `fs.product(...)`.
|
|
81
|
+
3. Compiles the business into deterministic Manifest IR.
|
|
82
|
+
4. Validates the result against the deployed platform contract.
|
|
83
|
+
5. Publishes the accepted release through Core so edge artifacts propagate.
|
|
84
|
+
|
|
85
|
+
The bundled `farthershore-manifest-build` binary is bot/build-runner plumbing.
|
|
86
|
+
Run it locally only when debugging the automation itself; it is not part of the
|
|
87
|
+
normal builder workflow.
|
|
88
|
+
|
|
89
|
+
## Public API
|
|
90
|
+
|
|
91
|
+
- `fs.business(name, options)` / `fs.product(name, options)` — create the
|
|
92
|
+
product builder.
|
|
93
|
+
- `business.meter(...)` — declare billable or enforceable dimensions.
|
|
94
|
+
- `business.resource(...)` — declare counted resources for resource-count
|
|
95
|
+
constraints.
|
|
96
|
+
- `business.capability(...)` — declare capability bundles and plan grants.
|
|
97
|
+
- `business.feature(...)` / `business.api.route(...)` — declare gateway routes,
|
|
98
|
+
meters, and action metadata.
|
|
99
|
+
- `business.policy(...)` — declare policy files in code.
|
|
100
|
+
- `business.plan(...)` — declare plan pricing, limits, grants, and lifecycle
|
|
101
|
+
behavior.
|
|
102
|
+
- `business.frontend.*` — declare generated portal navigation and gates.
|
|
103
|
+
- `business.lifecycle.*` — declare migrations.
|
|
104
|
+
- `business.raw.*` — escape hatches for platform-schema JSON when the typed SDK
|
|
105
|
+
does not yet have sugar.
|
|
106
|
+
|
|
107
|
+
## Determinism
|
|
108
|
+
|
|
109
|
+
`product.config.ts` must be deterministic: no dates, randomness, network calls,
|
|
110
|
+
or process state. Sorted collections produce stable output, while route order
|
|
111
|
+
remains semantic because the gateway matcher is first-match-wins.
|
|
112
|
+
|
|
113
|
+
The GitHub bot runs the build twice and rejects the push if the two generated
|
|
114
|
+
hashes differ.
|
|
115
|
+
|
|
116
|
+
## Release
|
|
117
|
+
|
|
118
|
+
`@farthershore/product` publishes to public npm through the GitHub workflow
|
|
119
|
+
`.github/workflows/publish-product-sdk.yml`.
|
|
120
|
+
|
|
121
|
+
Release sequence:
|
|
122
|
+
|
|
123
|
+
1. Bump `packages/product/package.json` version.
|
|
124
|
+
2. Run the package checks:
|
|
125
|
+
```bash
|
|
126
|
+
pnpm --filter @farthershore/product run lint
|
|
127
|
+
pnpm --filter @farthershore/product run test
|
|
128
|
+
pnpm --filter @farthershore/product run build
|
|
129
|
+
pnpm --filter @farthershore/product run pack:check
|
|
130
|
+
```
|
|
131
|
+
3. Commit, push, and merge through the normal PR flow.
|
|
132
|
+
4. Tag from `main` with the exact package version:
|
|
133
|
+
```bash
|
|
134
|
+
git tag product-v<version>
|
|
135
|
+
git push origin product-v<version>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The publish workflow verifies that the tag equals
|
|
139
|
+
`product-v<packages/product/package.json version>`, builds/tests the package and
|
|
140
|
+
its dependencies, runs `pack:check`, then publishes with `NPM_PUBLISH_TOKEN`.
|