@jarenjs/contract 0.49.2 → 0.66.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 (52) hide show
  1. package/README.md +191 -30
  2. package/dist/types/adapters/fetch.d.ts +11 -10
  3. package/dist/types/adapters/node.d.ts +24 -10
  4. package/dist/types/client/http.d.ts +77 -10
  5. package/dist/types/compat.d.ts +1 -1
  6. package/dist/types/errors.d.ts +3 -0
  7. package/dist/types/host.d.ts +179 -0
  8. package/dist/types/http/body.d.ts +147 -0
  9. package/dist/types/http/dispatch.d.ts +26 -2
  10. package/dist/types/http/serve.d.ts +46 -3
  11. package/dist/types/http/wire.d.ts +31 -17
  12. package/dist/types/ledger.d.ts +57 -12
  13. package/dist/types/local/index.d.ts +7 -1
  14. package/dist/types/messages.d.ts +2 -0
  15. package/dist/types/path.d.ts +4 -2
  16. package/dist/types/pipeline.d.ts +15 -1
  17. package/dist/types/port/client.d.ts +18 -1
  18. package/dist/types/port/serve.d.ts +38 -5
  19. package/dist/types/project/tools.d.ts +1 -1
  20. package/dist/types/project/typescript.d.ts +11 -0
  21. package/dist/types/runtime.d.ts +25 -0
  22. package/dist/types/stream/client.d.ts +14 -3
  23. package/dist/types/stream/server.d.ts +218 -44
  24. package/dist/types/stream/sse.d.ts +10 -0
  25. package/docs/APP-INTEGRATION.md +4 -2
  26. package/docs/CONTRACT-FORMAT.md +617 -145
  27. package/package.json +5 -5
  28. package/src/adapters/fetch.js +144 -25
  29. package/src/adapters/node.js +246 -82
  30. package/src/cli.js +22 -16
  31. package/src/client/http.js +588 -189
  32. package/src/compat.js +1 -1
  33. package/src/errors.js +3 -0
  34. package/src/host.js +319 -0
  35. package/src/http/body.js +337 -0
  36. package/src/http/dispatch.js +511 -75
  37. package/src/http/serve.js +39 -5
  38. package/src/http/wire.js +33 -14
  39. package/src/ledger.js +119 -36
  40. package/src/local/index.js +91 -35
  41. package/src/messages.js +2 -0
  42. package/src/path.js +9 -3
  43. package/src/pipeline.js +18 -1
  44. package/src/port/client.js +39 -6
  45. package/src/port/serve.js +207 -69
  46. package/src/project/tools.js +9 -2
  47. package/src/project/typescript.js +91 -1
  48. package/src/project/typescript.jtlt.json +39 -7
  49. package/src/runtime.js +36 -0
  50. package/src/stream/client.js +40 -6
  51. package/src/stream/server.js +573 -138
  52. package/src/stream/sse.js +2 -0
package/src/cli.js CHANGED
@@ -20,6 +20,7 @@ import * as path from 'node:path';
20
20
  import { compileContract } from './compile.js';
21
21
  import { ContractCompileError, ContractHostError } from './errors.js';
22
22
  import { diffContracts } from './diff.js';
23
+ import { loadDocument } from '@jarenjs/json/node';
23
24
  import { publicProjection } from './public.js';
24
25
  import { toOpenApi } from './project/openapi.js';
25
26
 
@@ -84,7 +85,11 @@ function parseArgs(argv) {
84
85
  case '--contract': options.contract = argv[++i] ?? null; break;
85
86
  case '--from': options.from = argv[++i] ?? null; break;
86
87
  case '--to': options.to = argv[++i] ?? null; break;
87
- case '--fail-on': options.failOn = argv[++i] ?? null; break;
88
+ case '--fail-on':
89
+ if (argv[i + 1] === undefined || argv[i + 1].startsWith('-'))
90
+ throw new Error('--fail-on needs at least one change class');
91
+ options.failOn = argv[++i];
92
+ break;
88
93
  case '--out': options.out = argv[++i] ?? null; break;
89
94
  case '--check': options.check = true; break;
90
95
  case '--lenient': options.lenient = true; break;
@@ -147,16 +152,22 @@ function fail(message, usage = false) {
147
152
  const DIFF_CLASSES = ['breaking', 'additive', 'neutral', 'unknown'];
148
153
 
149
154
  /**
150
- * Read a contract document, exit 2 on an unreadable file.
155
+ * Read a contract document — a `.json` file, or a pure module whose
156
+ * `default` (or `contract`) export is the document or a pen builder
157
+ * that emits one — through the suite's one loader (`@jarenjs/json/node`,
158
+ * shared with `jaren-db`): the module is evaluated twice and refused
159
+ * when the two emissions differ. Exit 2 on every refusal, naming the
160
+ * flag and the file.
151
161
  * @param {string} file
152
- * @param {string} flag
162
+ * @param {string} what - `contract`, or the diff flag (`--from`, `--to`)
163
+ * @returns {Promise<any>}
153
164
  */
154
- function readDocument(file, flag) {
165
+ async function readDocument(file, what) {
155
166
  try {
156
- return JSON.parse(fs.readFileSync(file, 'utf8'));
167
+ return await loadDocument(file, { what, exportName: 'contract' });
157
168
  }
158
169
  catch (error) {
159
- fail(`cannot read ${flag} '${file}': ${/** @type {Error} */ (error).message}`);
170
+ fail(/** @type {Error} */ (error).message);
160
171
  return null; // unreachable — fail() exits
161
172
  }
162
173
  }
@@ -166,18 +177,19 @@ function readDocument(file, flag) {
166
177
  * `--fail-on` exit 1 when a named class is non-empty.
167
178
  * @param {ReturnType<typeof parseArgs>} options
168
179
  */
169
- function runDiff(options) {
180
+ async function runDiff(options) {
170
181
  if (options.from === null || options.to === null) return fail('diff needs --from <file> and --to <file>', true);
171
182
  /** @type {string[]} */
172
183
  let failOn = [];
173
184
  if (options.failOn !== null) {
174
185
  failOn = options.failOn.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
186
+ if (failOn.length === 0) return fail('--fail-on needs at least one change class', true);
175
187
  for (const name of failOn) {
176
188
  if (!DIFF_CLASSES.includes(name)) return fail(`--fail-on '${name}' is not a change class (${DIFF_CLASSES.join(', ')})`, true);
177
189
  }
178
190
  }
179
- const from = readDocument(options.from, '--from');
180
- const to = readDocument(options.to, '--to');
191
+ const from = await readDocument(options.from, '--from');
192
+ const to = await readDocument(options.to, '--to');
181
193
  let diff;
182
194
  try {
183
195
  diff = diffContracts(from, to);
@@ -214,13 +226,7 @@ async function main() {
214
226
  if (options.contract === null) return fail('--contract <file> is required', true);
215
227
  if (options.check && options.out === null) return fail('--check needs --out', true);
216
228
 
217
- let doc;
218
- try {
219
- doc = JSON.parse(fs.readFileSync(options.contract, 'utf8'));
220
- }
221
- catch (error) {
222
- return fail(`cannot read contract '${options.contract}': ${/** @type {Error} */ (error).message}`);
223
- }
229
+ const doc = await readDocument(options.contract, 'contract');
224
230
  let rendered;
225
231
  try {
226
232
  const contract = compileContract(doc);