@requence/service 1.0.0-alpha.51 → 1.0.0-alpha.53

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 (29) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +235 -96
  3. package/build/cli.js +2 -1
  4. package/build/cli.js.map +3 -3
  5. package/build/index.js +69 -19
  6. package/build/index.js.map +6 -6
  7. package/build/types/helpers/src/files/RequenceFile.d.ts.map +1 -1
  8. package/build/types/helpers/src/files/RequenceStream.d.ts.map +1 -1
  9. package/build/types/helpers/src/files/isValidMimeType.d.ts.map +1 -1
  10. package/build/types/helpers/src/protocol/NodeTree.d.ts +16 -2
  11. package/build/types/helpers/src/protocol/NodeTree.d.ts.map +1 -1
  12. package/build/types/helpers/src/protocol/command.d.ts +26 -0
  13. package/build/types/helpers/src/protocol/command.d.ts.map +1 -1
  14. package/build/types/helpers/src/protocol/nodeType.d.ts +10 -0
  15. package/build/types/helpers/src/protocol/nodeType.d.ts.map +1 -1
  16. package/build/types/helpers/src/protocol/taskOptions.d.ts +3 -0
  17. package/build/types/helpers/src/protocol/taskOptions.d.ts.map +1 -1
  18. package/build/types/helpers/src/protocol/templateNodeTypes.d.ts.map +1 -1
  19. package/build/types/helpers/src/protocol/treeNodes.d.ts +38 -0
  20. package/build/types/helpers/src/protocol/treeNodes.d.ts.map +1 -1
  21. package/build/types/helpers/src/protocol/update.d.ts +23 -0
  22. package/build/types/helpers/src/protocol/update.d.ts.map +1 -1
  23. package/build/types/helpers/src/utils/callbackToAsyncIterator.d.ts +1 -1
  24. package/build/types/helpers/src/utils/callbackToAsyncIterator.d.ts.map +1 -1
  25. package/build/types/service/src/createAmqpConnection.d.ts +1 -1
  26. package/build/types/service/src/createAmqpConnection.d.ts.map +1 -1
  27. package/build/types/service/src/helpers.d.ts +6 -2
  28. package/build/types/service/src/helpers.d.ts.map +1 -1
  29. package/package.json +7 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @requence/service
2
2
 
3
+ ## 1.0.0-alpha.53
4
+
5
+ ### Patch Changes
6
+
7
+ - 7fdea3b: lint
8
+
9
+ ## 1.0.0-alpha.52
10
+
11
+ ### Patch Changes
12
+
13
+ - 6922266: trace ids
14
+
3
15
  ## 1.0.0-alpha.51
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -1,191 +1,330 @@
1
- # @requence/consumer
1
+ # @requence/service
2
2
 
3
- This package connects a JavaScript runtime (e.g. Node.js / Bun) to the operator bus. It manages the retrieval and responses of messages.
3
+ This package connects a TypeScript / Bun service to the Requence operator. It manages message retrieval, processing, and result delivery.
4
4
 
5
- ## Usage
5
+ ## Installation
6
6
 
7
- ```typescript
8
- import createConsumer from '@requence/consumer'
7
+ ```bash
8
+ npm install @requence/service
9
+ ```
9
10
 
10
- createConsumer((ctx) => {
11
- return 'this is my response'
12
- })
11
+ ## Authentication
12
+
13
+ Every service needs an **access token** to connect. Copy it from the **Services** list view in the Requence UI by clicking **Copy credentials**.
14
+
15
+ The token is resolved in this order:
16
+
17
+ 1. `accessToken` option passed to `createService()`
18
+ 2. `REQUENCE_SERVICE_ACCESS_TOKEN` or `REQUENCE_ACCESS_TOKEN` environment variable
19
+ 3. `requence.service.accessToken` or `requence.accessToken` in `package.json`
20
+
21
+ ```bash
22
+ REQUENCE_SERVICE_ACCESS_TOKEN=your-token bun run index.ts
13
23
  ```
14
24
 
15
- Every consumer instance needs a `url` parameter to connect to the operator and a `version`. In the basic example, those parameters get automatically retrieved from environment variables `REQUENCE_URL` and `VERSION`.
16
- To be more explicit about those configurations, you can pass an object as the first parameter:
25
+ ## Usage
17
26
 
18
27
  ```typescript
19
- createConsumer(
20
- {
21
- url: 'your operator connection url string',
22
- version: 'your version in format major.minor.patch',
23
- },
24
- (ctx) => {
25
- return 'this is my response'
26
- },
27
- )
28
+ import { createService } from '@requence/service'
29
+
30
+ createService('1.0.0', (ctx) => {
31
+ return { message: `Hello, ${ctx.input.name}!` }
32
+ })
28
33
  ```
29
34
 
30
- ## Additional configuration
35
+ The second argument to `createService` is the **version** of the service definition you are implementing. When Requence dispatches a message, the handler runs and the return value is sent back as the result.
31
36
 
32
- By default, the consumer retrieves one message from the operator, processes it and passes the response back to the operator. If your service is capable of processing multiple messages in parallel, you can define a higher `prefetch`.
37
+ ### Options object
38
+
39
+ Instead of a bare version string, you can pass an options object:
33
40
 
34
41
  ```typescript
35
- createConsumer(
42
+ import { createService } from '@requence/service'
43
+
44
+ createService(
36
45
  {
37
- prefetch: 10, // this will process max. 10 messages at once when available
46
+ version: '1.0.0',
47
+ prefetch: 5, // process up to 5 messages in parallel (default: 1)
48
+ connectionTimeout: 30_000, // ms to wait before throwing (default: 3000)
49
+ silent: false, // suppress lifecycle logs
38
50
  },
39
51
  async (ctx) => {
40
- return 'this is my response'
52
+ return processData(ctx.input)
41
53
  },
42
54
  )
43
55
  ```
44
56
 
45
- ## Unsubscribing service
57
+ ### Return value
46
58
 
47
- Should you ever need to unsubscribe your service from the operator programmatically, `createConsumer` returns a promise with an unsubscribe function.
59
+ `createService` returns a `ServiceApi` object immediately (the connection is established in the background):
48
60
 
49
61
  ```typescript
50
- const unsubscribe = await createConsumer(...)
62
+ const service = createService('1.0.0', handler)
51
63
 
52
- // later
53
- unsubscribe()
64
+ // wait for the connection to be ready
65
+ await service.open()
66
+
67
+ // gracefully close the connection
68
+ await service.close()
54
69
  ```
55
70
 
56
- To resubscribe, you have to call `createConsumer` again
71
+ ## Context API
72
+
73
+ Every handler receives a `ctx` object.
57
74
 
58
- ## Processing messages
75
+ ### Data access
59
76
 
60
- The message handler callback provides one argument: the message context.
61
- The context provides helper methods to access previous operator results and also methods to abort the processing early.
77
+ | Property | Description |
78
+ |---|---|
79
+ | `ctx.input` | The input data routed to this service node from the task template |
80
+ | `ctx.configuration` | The static configuration set on the service node in the UI |
81
+ | `ctx.taskId` | The unique ID of the current task execution |
62
82
 
63
- ### context api data retrieval
83
+ ### Logging
84
+
85
+ `ctx.debug` sends log messages to the Requence UI in real time:
64
86
 
65
87
  ```typescript
66
- ctx.getInput()
88
+ ctx.debug.log('Processing started')
89
+ ctx.debug.info('Step complete', { step: 1 })
90
+ ctx.debug.warn('Something looks off')
91
+ ctx.debug.error('An error occurred', error)
67
92
  ```
68
93
 
69
- The input that was defined when the task started
94
+ ### Flow control
95
+
96
+ #### `ctx.retry(delay?)`
97
+
98
+ Instructs Requence to retry this service after an optional delay in milliseconds (minimum 100 ms). No code executes after this call.
70
99
 
71
100
  ```typescript
72
- ctx.getMeta()
101
+ createService('1.0.0', async (ctx) => {
102
+ const db = await getDbConnection()
103
+
104
+ if (!db.isConnected) {
105
+ ctx.retry(2_000) // retry in 2 seconds
106
+ }
107
+
108
+ return db.query('SELECT ...')
109
+ })
73
110
  ```
74
111
 
75
- The additional meta information added to the task
112
+ > **Note:** It is your responsibility to prevent infinite retry loops.
113
+
114
+ #### `ctx.abort(reason?)`
115
+
116
+ Instructs Requence to abort this service immediately. If the service node's **on fail** output is not connected, the entire task fails.
76
117
 
77
118
  ```typescript
78
- ctx.getConfiguration(): unknown
119
+ createService('1.0.0', (ctx) => {
120
+ if (!ctx.input.requiredField) {
121
+ ctx.abort('Missing required field')
122
+ }
123
+
124
+ return processData(ctx.input)
125
+ })
79
126
  ```
80
127
 
81
- The optional configuration of the current service
128
+ #### `ctx.skip()`
129
+
130
+ Puts the message back on the queue without processing it. The next available service instance will receive it instead.
131
+
132
+ #### `ctx.toOutput(name, value)`
133
+
134
+ Routes the result to a specific **named output** on the service node. Use this when your service definition has multiple outputs:
82
135
 
83
136
  ```typescript
84
- ctx.getServiceMeta(serviceIdentifier): {
85
- executionDate: Date | null, // null when the service was not yet executed
86
- id: string, // service id used for internal routing
87
- alias?: string, // service alias (see service Identifier)
88
- name: string,
89
- configuration?: unknown,
90
- version: string
91
- }
137
+ createService('1.0.0', (ctx) => {
138
+ if (ctx.input.type === 'pdf') {
139
+ return ctx.toOutput('pdf', { url: '...' })
140
+ }
141
+
142
+ return ctx.toOutput('other', { raw: ctx.input })
143
+ })
92
144
  ```
93
145
 
94
- The meta parameters of a service, usually not needed
146
+ #### `ctx.defer(reason?)`
147
+
148
+ Marks the message as **deferred**. The service acknowledges the message but signals that the result will be delivered later via `service.act()`. Returns a **message key** that you must store and pass to `act()`:
95
149
 
96
150
  ```typescript
97
- ctx.getServiceData(serviceIdentifier): unknown
151
+ createService('1.0.0', (ctx) => {
152
+ const messageKey = ctx.defer('waiting for external process')
153
+ externalQueue.push({ messageKey, payload: ctx.input })
154
+ // handler returns — message is held open until act() is called
155
+ })
98
156
  ```
99
157
 
100
- The response of a previously executed service
158
+ #### `ctx.terminated`
159
+
160
+ A `Promise` that resolves when the task is stopped (cancelled via the UI or API, or terminated by another node). Use it in continuous/generator services to know when to stop producing values.
161
+
162
+ `ctx.terminated.signal` is a native [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that fires at the same moment — pass it to any abort-aware API:
101
163
 
102
164
  ```typescript
103
- ctx.getLastServiceData(serviceIdentifier): unknown
165
+ import { setTimeout } from 'node:timers/promises'
166
+ import { createService } from '@requence/service'
167
+
168
+ // Poll every 5 seconds, exit immediately when the task is stopped
169
+ createService('1.0.0', async function* (ctx) {
170
+ while (true) {
171
+ await setTimeout(5_000, null, { signal: ctx.terminated.signal })
172
+ yield await pollForUpdates()
173
+ }
174
+ })
104
175
  ```
105
176
 
106
- Same as `ctx.getServiceData` but only returns the last data when a service is used multiple times
177
+ Or race against it directly:
107
178
 
108
179
  ```typescript
109
- ctx.getServiceError(serviceIdentifier): string | null
180
+ const result = await Promise.race([
181
+ fetchData(),
182
+ ctx.terminated,
183
+ ])
110
184
  ```
111
185
 
112
- The error message of a previously executed service or null when said service was not yet executed or did process without error.
186
+ > The framework automatically catches the `AbortError` thrown by abort-aware APIs when the task is terminated no `try/catch` needed inside a generator.
187
+
188
+ ## Continuous (Generator) Mode
189
+
190
+ When a service node is configured in **continuous mode**, the handler can be an async generator. Each `yield` sends an incremental result to Requence; the final `return` (or generator completion) signals the end of processing:
113
191
 
114
192
  ```typescript
115
- ctx.getLastServiceError(serviceIdentifier): string | null
193
+ createService('1.0.0', async function* (ctx) {
194
+ for (const chunk of await fetchChunks(ctx.input)) {
195
+ yield { chunk }
196
+ }
197
+ })
116
198
  ```
117
199
 
118
- Same as `ctx.getServiceError` but only returns the last error when a service is used multiple times
200
+ The generator is terminated automatically when `ctx.terminated` resolves. Yielded values are still sent before the generator exits.
201
+
202
+ ## Deferred Delivery via `service.act()`
203
+
204
+ After deferring a message with `ctx.defer()`, use `service.act()` to deliver the result later — even from a different process run:
119
205
 
120
206
  ```typescript
121
- ctx.getResults(): Array<{
122
- executionDate: Date | null, // null when the service was not yet executed
123
- id: string, // service id used for internal routing
124
- alias?: string, // service alias (see service Identifier)
125
- name: string,
126
- configuration?: unknown,
127
- version: string
128
- error?: string
129
- data?: unknown | null
130
- }>
207
+ const service = createService('1.0.0', (ctx) => {
208
+ const messageKey = ctx.defer()
209
+ saveMessageKey(ctx.taskId, messageKey)
210
+ })
211
+
212
+ // ... in a webhook handler or background job:
213
+ await service.act(messageKey, async (api) => {
214
+ api.send({ result: 'done' })
215
+ // or: api.sendToOutput('success', { result: 'done' })
216
+ // or: api.abort('something went wrong')
217
+ })
131
218
  ```
132
219
 
133
- get results of all configured services in this task. When a service did run prior to the current service, `executionDate` and `error` or `data` will be available.
220
+ `act()` also supports returning a value or an iterable directly from the actor function, which behaves the same as calling `api.send()` for each value.
221
+
222
+ ## Dev Overlay
223
+
224
+ When developing locally alongside a production service, use a **dev token** (your personal access token) to register a dev instance. Requence routes your own tasks to the dev instance instead of the production pool:
134
225
 
135
226
  ```typescript
136
- ctx.getTenantName(): String
227
+ import { createService } from '@requence/service'
228
+
229
+ createService(
230
+ {
231
+ version: '1.0.0',
232
+ devToken: process.env.REQUENCE_DEV_TOKEN,
233
+ },
234
+ (ctx) => ctx.input,
235
+ )
137
236
  ```
138
237
 
139
- The name of the tenant that initiated the task
238
+ The dev token is resolved in the same order as the access token — option, `REQUENCE_SERVICE_DEV_TOKEN` / `REQUENCE_DEV_TOKEN` env var, or `requence.service.devToken` / `requence.devToken` in `package.json`.
140
239
 
141
- ### context api processing control
240
+ ## CLI Generate Types
142
241
 
143
- ```typescript
144
- ctx.retry(delay?: number): never
242
+ The package ships with a CLI that generates TypeScript types derived from the schemas you defined in the Requence UI (input, configuration, and outputs):
243
+
244
+ ```bash
245
+ npx requence-service generate-types
246
+ ```
247
+
248
+ This creates a `requence-env.d.ts` file in your project root. TypeScript picks it up automatically — `ctx.input`, `ctx.configuration`, and `ctx.toOutput()` calls become fully typed.
249
+
250
+ ### Options
251
+
252
+ | Option | Default | Description |
253
+ |---|---|---|
254
+ | `--access-token` | — | Service access token (falls back to env / config file) |
255
+ | `--dev-token` | — | Personal access token for branch-specific types |
256
+ | `--outfile` | `requence-env.d.ts` | Name of the generated type file |
257
+ | `--outdir` | `.` | Directory to write the type file to |
258
+ | `--watch` | `false` | Watch for schema changes and regenerate automatically |
259
+ | `--clear` / `--no-clear` | `true` | Clear the terminal on watch updates |
260
+
261
+ ### Watch mode
262
+
263
+ ```bash
264
+ npx requence-service generate-types --watch
145
265
  ```
146
266
 
147
- Instructs the operator to retry the service after an optional delay in milliseconds (minimum is 100ms). No code gets executed after this line.
148
- **Currently, it is your responsibility to prevent infinite loops.**
267
+ The CLI connects via server-sent events and regenerates types whenever a schema changes in the UI.
268
+
269
+ ## Utility Helpers
270
+
271
+ ### `wrapIterable(iterable)`
272
+
273
+ Wraps any `Iterable` or `AsyncIterable` so that iteration stops automatically when `ctx.terminated` resolves:
149
274
 
150
275
  ```typescript
151
- ctx.abort(reason?: string): never
276
+ import { wrapIterable } from '@requence/service'
277
+
278
+ createService('1.0.0', async function* (ctx) {
279
+ for await (const event of wrapIterable(eventStream)) {
280
+ yield processEvent(event)
281
+ }
282
+ })
152
283
  ```
153
284
 
154
- Instructs the operator to abort the processing of this service immediately.
155
- If the service is not configured with a fail over, the complete task will fail.
285
+ ### `asyncEventEmitter(initial?)`
156
286
 
157
- ### service identifier
287
+ Creates an async-iterable event emitter that integrates with `ctx.terminated`. Push values from outside (e.g. callbacks or event listeners) and iterate them inside the generator:
158
288
 
159
- Most context methods require a service identifier as parameter. This identifier can either be a service name or a service alias. The latter is useful for situations where a service is used multiple times in a task and needs the data from one specific execution.
289
+ ```typescript
290
+ import { asyncEventEmitter, createService } from '@requence/service'
160
291
 
161
- ## Full example
292
+ createService('1.0.0', async function* (ctx) {
293
+ const emitter = asyncEventEmitter<string>()
162
294
 
163
- Pseudo implementation of a database service
295
+ externalSource.on('data', (value) => emitter.push(value))
296
+
297
+ for await (const value of emitter) {
298
+ yield { value }
299
+ }
300
+ })
301
+ ```
302
+
303
+ The iterator exits automatically when the task is terminated.
304
+
305
+ ## Full Example
164
306
 
165
307
  ```typescript
166
- import createConsumer from '@requence/consumer'
167
- import db from './database.js' // pseudo code
168
- createConsumer(
308
+ import { createService } from '@requence/service'
309
+ import { db } from './database.js'
310
+
311
+ createService(
169
312
  {
170
- url: 'amqp://username:password@host',
171
313
  version: '1.2.3',
172
- prefetch: 2, // we can process 2 messages in parallel
314
+ prefetch: 2, // process 2 messages in parallel
173
315
  },
174
316
  async (ctx) => {
175
- const ocrData = ctx.getServiceData('ocr')
176
-
177
- if (!ocrData) {
178
- ctx.abort('Ocr service is mandatory for this AI service')
317
+ if (!db.isConnected) {
318
+ ctx.retry(2_000) // wait 2s for the DB to recover
179
319
  }
180
320
 
181
- if (!db.isConnected) {
182
- // lets wait 2s for the db to recover
183
- ctx.retry(2000)
321
+ if (!ctx.input.ocrData) {
322
+ ctx.abort('OCR data is mandatory')
184
323
  }
185
324
 
186
- const response = await db.getDataBasedOnOcr(ocrData)
325
+ const result = await db.getDataBasedOnOcr(ctx.input.ocrData)
187
326
 
188
- return response
327
+ return result
189
328
  },
190
329
  )
191
330
  ```
package/build/cli.js CHANGED
@@ -56,6 +56,7 @@ async function fetchTypes(url, headers, targetFile, clear = false, showTimestamp
56
56
  `;
57
57
  }
58
58
  const data = `${header}/* eslint-disable */
59
+ /* oxlint-disable */
59
60
  /* prettier-ignore */
60
61
 
61
62
  ${text}`;
@@ -156,5 +157,5 @@ in your ${chalk.bold("package.json")} in ${chalk.bold("requence.accessToken")} /
156
157
  });
157
158
  }).scriptName("requence-service").help("h").demandCommand(1, 1).strict().parse();
158
159
 
159
- //# debugId=190F4F01CE4319C364756E2164756E21
160
+ //# debugId=F3C67DF0D72FBC3064756E2164756E21
160
161
  //# sourceMappingURL=cli.js.map
package/build/cli.js.map CHANGED
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/cli.ts"],
4
4
  "sourcesContent": [
5
- "#!/usr/bin/env node\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport { deobfuscate } from '@requence/helpers'\nimport chalk from 'chalk'\nimport { createEventSource } from 'eventsource-client'\nimport yargs from 'yargs'\nimport { hideBin } from 'yargs/helpers'\nimport { z } from 'zod/v4'\n\nconst y = yargs(hideBin(process.argv))\n\nconst colors = {\n red: chalk.hex('#ef4444'),\n green: chalk.hex('#22c55e'),\n yellow: chalk.hex('#eab308'),\n orange: chalk.hex('#f97316'),\n zinc: chalk.hex('#71717a'),\n}\n\nfunction errorExit(title: string, text?: string): never {\n console.error(colors.red.bold(title + '\\n'))\n if (text) {\n console.error(colors.red(text) + '\\n')\n }\n process.exit(1)\n}\n\nlet pkgJson: any | null\nfunction loadPkgJson() {\n if (!pkgJson) {\n pkgJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'))\n }\n return pkgJson\n}\n\nasync function fetchTypes(\n url: string,\n headers: HeadersInit,\n targetFile: string,\n clear = false,\n showTimestamp = false,\n) {\n const timestamp = () =>\n colors.zinc(new Date().toLocaleTimeString('en-GB', { hour12: false }))\n const response = await fetch(url, {\n method: 'GET',\n headers,\n })\n\n const branchName = response.headers.get('x-branch-name')\n const text = await response.text()\n\n if (!response.ok) {\n errorExit(text)\n }\n\n let header =\n '// Generated by requence-service CLI — DO NOT EDIT.\\n// Changes will be overwritten.\\n\\n'\n\n if (branchName) {\n header += `// !!! types for branch \"${branchName}\" !!!\\n\\n`\n }\n const data = `${header}/* eslint-disable */\\n/* prettier-ignore */\\n\\n${text}`\n\n fs.writeFileSync(targetFile, data)\n\n if (clear) {\n console.clear()\n }\n\n if (branchName) {\n console.info(\n ...(showTimestamp ? [timestamp()] : []),\n colors.yellow(\n 'types for branch',\n chalk.bold(branchName),\n 'saved to',\n chalk.bold(path.relative(process.cwd(), targetFile)),\n ),\n )\n } else {\n console.info(\n ...(showTimestamp ? [timestamp()] : []),\n colors.green(\n 'types saved to',\n chalk.bold(path.relative(process.cwd(), targetFile)),\n ),\n )\n }\n}\n\ny.command(\n 'generate-types',\n 'generates typescript types',\n (yargs) =>\n yargs\n .option('access-token', {\n describe: 'access token',\n type: 'string',\n })\n .option('dev-token', {\n description: 'dev token',\n type: 'string',\n })\n .option('outfile', {\n default: 'requence-env.d.ts',\n })\n .option('outdir', {\n default: '',\n })\n .option('watch', {\n type: 'boolean',\n })\n .option('clear', {\n description:\n 'clear the terminal on watch updates (use --no-clear to disable)',\n type: 'boolean',\n default: true,\n }),\n async (argv) => {\n let token =\n argv.accessToken ??\n process.env.REQUENCE_SERVICE_ACCESS_TOKEN ??\n process.env.REQUENCE_ACCESS_TOKEN\n\n if (!token) {\n const pkgJson = loadPkgJson()\n token =\n pkgJson.requence?.service?.accessToken ?? pkgJson.requence?.accessToken\n }\n\n if (argv.clear) {\n console.info() // newline\n }\n if (!token) {\n errorExit(\n 'No access token found',\n `You can provide the access token as argument to ${chalk.bold('requence-service')},\\nas environment variable ${chalk.bold('REQUENCE_ACCESS_TOKEN')} / ${chalk.bold('REQUENCE_SERVICE_ACCESS_TOKEN')} or\\nin your ${chalk.bold('package.json')} in ${chalk.bold('requence.accessToken')} / ${chalk.bold('requence.service.accessToken')}`,\n )\n }\n\n const parts = deobfuscate(token)\n if (parts.length !== 3 || parts[0] !== 'service') {\n errorExit('Invalid service key')\n }\n\n const [, connectionString, serverUrl] = parts\n const headers: HeadersInit = {\n Authorization: `Bearer ${connectionString}`,\n }\n let devToken =\n argv.devToken ??\n process.env.REQUENCE_SERVICE_ACCESS_TOKEN ??\n process.env.REQUENCE_ACCESS_TOKEN\n\n if (!devToken) {\n const pkgJson = loadPkgJson()\n devToken =\n pkgJson.requence?.service?.devToken ?? pkgJson.requence?.devToken\n }\n\n if (devToken) {\n const devParts = deobfuscate(devToken)\n if (devParts[0] !== 'api') {\n throw new Error(\n 'invalid dev token: please provide a personal access token',\n )\n }\n if (devParts[2] !== parts[2]) {\n throw new Error(\n 'invalid dev token: access token and dev token belong to different requence instances',\n )\n }\n\n headers['x-dev-authorization'] = devParts[1]\n }\n\n await fetchTypes(\n serverUrl + '/service/types/typescript',\n headers,\n path.join(argv.outdir || process.cwd(), argv.outfile),\n )\n\n if (!argv.watch) {\n return\n }\n\n if (argv.clear) {\n console.clear()\n }\n console.info(colors.orange.bold('Watching for type changes…'))\n let lastWrite = Date.now()\n const timeSchema = z.coerce.number().int().positive()\n createEventSource({\n method: 'GET',\n url: serverUrl + '/service/watch',\n headers,\n async onMessage({ data }) {\n const timeResult = timeSchema.safeParse(data)\n if (!timeResult.success || timeResult.data < lastWrite) {\n return\n }\n lastWrite = timeResult.data\n if (argv.clear) {\n console.clear()\n }\n console.info(\n colors.zinc.bold(`Regenerating types…${argv.clear ? '\\n\\n' : ''}`),\n )\n\n await fetchTypes(\n serverUrl + '/service/types/typescript',\n headers,\n path.join(argv.outdir || process.cwd(), argv.outfile),\n argv.clear,\n true,\n )\n console.info(\n colors.orange.bold(\n `${argv.clear ? '\\n\\n' : ''}Watching for type changes…`,\n ),\n )\n },\n })\n },\n)\n .scriptName('requence-service')\n .help('h')\n .demandCommand(1, 1)\n .strict()\n .parse()\n"
5
+ "#!/usr/bin/env node\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport { deobfuscate } from '@requence/helpers'\nimport chalk from 'chalk'\nimport { createEventSource } from 'eventsource-client'\nimport yargs from 'yargs'\nimport { hideBin } from 'yargs/helpers'\nimport { z } from 'zod/v4'\n\nconst y = yargs(hideBin(process.argv))\n\nconst colors = {\n red: chalk.hex('#ef4444'),\n green: chalk.hex('#22c55e'),\n yellow: chalk.hex('#eab308'),\n orange: chalk.hex('#f97316'),\n zinc: chalk.hex('#71717a'),\n}\n\nfunction errorExit(title: string, text?: string): never {\n console.error(colors.red.bold(title + '\\n'))\n if (text) {\n console.error(colors.red(text) + '\\n')\n }\n process.exit(1)\n}\n\nlet pkgJson: any | null\nfunction loadPkgJson() {\n if (!pkgJson) {\n pkgJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'))\n }\n return pkgJson\n}\n\nasync function fetchTypes(\n url: string,\n headers: HeadersInit,\n targetFile: string,\n clear = false,\n showTimestamp = false,\n) {\n const timestamp = () =>\n colors.zinc(new Date().toLocaleTimeString('en-GB', { hour12: false }))\n const response = await fetch(url, {\n method: 'GET',\n headers,\n })\n\n const branchName = response.headers.get('x-branch-name')\n const text = await response.text()\n\n if (!response.ok) {\n errorExit(text)\n }\n\n let header =\n '// Generated by requence-service CLI — DO NOT EDIT.\\n// Changes will be overwritten.\\n\\n'\n\n if (branchName) {\n header += `// !!! types for branch \"${branchName}\" !!!\\n\\n`\n }\n const data = `${header}/* eslint-disable */\\n/* oxlint-disable */\\n/* prettier-ignore */\\n\\n${text}`\n\n fs.writeFileSync(targetFile, data)\n\n if (clear) {\n console.clear()\n }\n\n if (branchName) {\n console.info(\n ...(showTimestamp ? [timestamp()] : []),\n colors.yellow(\n 'types for branch',\n chalk.bold(branchName),\n 'saved to',\n chalk.bold(path.relative(process.cwd(), targetFile)),\n ),\n )\n } else {\n console.info(\n ...(showTimestamp ? [timestamp()] : []),\n colors.green(\n 'types saved to',\n chalk.bold(path.relative(process.cwd(), targetFile)),\n ),\n )\n }\n}\n\ny.command(\n 'generate-types',\n 'generates typescript types',\n (yargs) =>\n yargs\n .option('access-token', {\n describe: 'access token',\n type: 'string',\n })\n .option('dev-token', {\n description: 'dev token',\n type: 'string',\n })\n .option('outfile', {\n default: 'requence-env.d.ts',\n })\n .option('outdir', {\n default: '',\n })\n .option('watch', {\n type: 'boolean',\n })\n .option('clear', {\n description:\n 'clear the terminal on watch updates (use --no-clear to disable)',\n type: 'boolean',\n default: true,\n }),\n async (argv) => {\n let token =\n argv.accessToken ??\n process.env.REQUENCE_SERVICE_ACCESS_TOKEN ??\n process.env.REQUENCE_ACCESS_TOKEN\n\n if (!token) {\n const pkgJson = loadPkgJson()\n token =\n pkgJson.requence?.service?.accessToken ?? pkgJson.requence?.accessToken\n }\n\n if (argv.clear) {\n console.info() // newline\n }\n if (!token) {\n errorExit(\n 'No access token found',\n `You can provide the access token as argument to ${chalk.bold('requence-service')},\\nas environment variable ${chalk.bold('REQUENCE_ACCESS_TOKEN')} / ${chalk.bold('REQUENCE_SERVICE_ACCESS_TOKEN')} or\\nin your ${chalk.bold('package.json')} in ${chalk.bold('requence.accessToken')} / ${chalk.bold('requence.service.accessToken')}`,\n )\n }\n\n const parts = deobfuscate(token)\n if (parts.length !== 3 || parts[0] !== 'service') {\n errorExit('Invalid service key')\n }\n\n const [, connectionString, serverUrl] = parts\n const headers: HeadersInit = {\n Authorization: `Bearer ${connectionString}`,\n }\n let devToken =\n argv.devToken ??\n process.env.REQUENCE_SERVICE_ACCESS_TOKEN ??\n process.env.REQUENCE_ACCESS_TOKEN\n\n if (!devToken) {\n const pkgJson = loadPkgJson()\n devToken =\n pkgJson.requence?.service?.devToken ?? pkgJson.requence?.devToken\n }\n\n if (devToken) {\n const devParts = deobfuscate(devToken)\n if (devParts[0] !== 'api') {\n throw new Error(\n 'invalid dev token: please provide a personal access token',\n )\n }\n if (devParts[2] !== parts[2]) {\n throw new Error(\n 'invalid dev token: access token and dev token belong to different requence instances',\n )\n }\n\n headers['x-dev-authorization'] = devParts[1]\n }\n\n await fetchTypes(\n serverUrl + '/service/types/typescript',\n headers,\n path.join(argv.outdir || process.cwd(), argv.outfile),\n )\n\n if (!argv.watch) {\n return\n }\n\n if (argv.clear) {\n console.clear()\n }\n console.info(colors.orange.bold('Watching for type changes…'))\n let lastWrite = Date.now()\n const timeSchema = z.coerce.number().int().positive()\n createEventSource({\n method: 'GET',\n url: serverUrl + '/service/watch',\n headers,\n async onMessage({ data }) {\n const timeResult = timeSchema.safeParse(data)\n if (!timeResult.success || timeResult.data < lastWrite) {\n return\n }\n lastWrite = timeResult.data\n if (argv.clear) {\n console.clear()\n }\n console.info(\n colors.zinc.bold(`Regenerating types…${argv.clear ? '\\n\\n' : ''}`),\n )\n\n await fetchTypes(\n serverUrl + '/service/types/typescript',\n headers,\n path.join(argv.outdir || process.cwd(), argv.outfile),\n argv.clear,\n true,\n )\n console.info(\n colors.orange.bold(\n `${argv.clear ? '\\n\\n' : ''}Watching for type changes…`,\n ),\n )\n },\n })\n },\n)\n .scriptName('requence-service')\n .help('h')\n .demandCommand(1, 1)\n .strict()\n .parse()\n"
6
6
  ],
7
- "mappings": ";;;;;;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA,IAAM,IAAI,MAAM,QAAQ,QAAQ,IAAI,CAAC;AAErC,IAAM,SAAS;AAAA,EACb,KAAK,MAAM,IAAI,SAAS;AAAA,EACxB,OAAO,MAAM,IAAI,SAAS;AAAA,EAC1B,QAAQ,MAAM,IAAI,SAAS;AAAA,EAC3B,QAAQ,MAAM,IAAI,SAAS;AAAA,EAC3B,MAAM,MAAM,IAAI,SAAS;AAC3B;AAEA,SAAS,SAAS,CAAC,OAAe,MAAsB;AAAA,EACtD,QAAQ,MAAM,OAAO,IAAI,KAAK,QAAQ;AAAA,CAAI,CAAC;AAAA,EAC3C,IAAI,MAAM;AAAA,IACR,QAAQ,MAAM,OAAO,IAAI,IAAI,IAAI;AAAA,CAAI;AAAA,EACvC;AAAA,EACA,QAAQ,KAAK,CAAC;AAAA;AAGhB,IAAI;AACJ,SAAS,WAAW,GAAG;AAAA,EACrB,KAAK,SAAS;AAAA,IACZ,UAAU,KAAK,MAAM,GAAG,aAAa,gBAAgB,OAAO,CAAC;AAAA,EAC/D;AAAA,EACA,OAAO;AAAA;AAGT,eAAe,UAAU,CACvB,KACA,SACA,YACA,QAAQ,OACR,gBAAgB,OAChB;AAAA,EACA,MAAM,YAAY,MAChB,OAAO,KAAK,IAAI,KAAK,EAAE,mBAAmB,SAAS,EAAE,QAAQ,MAAM,CAAC,CAAC;AAAA,EACvE,MAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAAA,EAED,MAAM,aAAa,SAAS,QAAQ,IAAI,eAAe;AAAA,EACvD,MAAM,OAAO,MAAM,SAAS,KAAK;AAAA,EAEjC,KAAK,SAAS,IAAI;AAAA,IAChB,UAAU,IAAI;AAAA,EAChB;AAAA,EAEA,IAAI,SACF;AAAA;AAAA;AAAA;AAAA,EAEF,IAAI,YAAY;AAAA,IACd,UAAU,4BAA4B;AAAA;AAAA;AAAA,EACxC;AAAA,EACA,MAAM,OAAO,GAAG;AAAA;AAAA;AAAA,EAAwD;AAAA,EAExE,GAAG,cAAc,YAAY,IAAI;AAAA,EAEjC,IAAI,OAAO;AAAA,IACT,QAAQ,MAAM;AAAA,EAChB;AAAA,EAEA,IAAI,YAAY;AAAA,IACd,QAAQ,KACN,GAAI,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,GACrC,OAAO,OACL,oBACA,MAAM,KAAK,UAAU,GACrB,YACA,MAAM,KAAK,KAAK,SAAS,QAAQ,IAAI,GAAG,UAAU,CAAC,CACrD,CACF;AAAA,EACF,EAAO;AAAA,IACL,QAAQ,KACN,GAAI,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,GACrC,OAAO,MACL,kBACA,MAAM,KAAK,KAAK,SAAS,QAAQ,IAAI,GAAG,UAAU,CAAC,CACrD,CACF;AAAA;AAAA;AAIJ,EAAE,QACA,kBACA,8BACA,CAAC,WACC,OACG,OAAO,gBAAgB;AAAA,EACtB,UAAU;AAAA,EACV,MAAM;AACR,CAAC,EACA,OAAO,aAAa;AAAA,EACnB,aAAa;AAAA,EACb,MAAM;AACR,CAAC,EACA,OAAO,WAAW;AAAA,EACjB,SAAS;AACX,CAAC,EACA,OAAO,UAAU;AAAA,EAChB,SAAS;AACX,CAAC,EACA,OAAO,SAAS;AAAA,EACf,MAAM;AACR,CAAC,EACA,OAAO,SAAS;AAAA,EACf,aACE;AAAA,EACF,MAAM;AAAA,EACN,SAAS;AACX,CAAC,GACL,OAAO,SAAS;AAAA,EACd,IAAI,QACF,KAAK,eACL,QAAQ,IAAI,iCACZ,QAAQ,IAAI;AAAA,EAEd,KAAK,OAAO;AAAA,IACV,MAAM,WAAU,YAAY;AAAA,IAC5B,QACE,SAAQ,UAAU,SAAS,eAAe,SAAQ,UAAU;AAAA,EAChE;AAAA,EAEA,IAAI,KAAK,OAAO;AAAA,IACd,QAAQ,KAAK;AAAA,EACf;AAAA,EACA,KAAK,OAAO;AAAA,IACV,UACE,yBACA,mDAAmD,MAAM,KAAK,kBAAkB;AAAA,0BAA+B,MAAM,KAAK,uBAAuB,OAAO,MAAM,KAAK,+BAA+B;AAAA,UAAiB,MAAM,KAAK,cAAc,QAAQ,MAAM,KAAK,sBAAsB,OAAO,MAAM,KAAK,8BAA8B,GACvU;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,YAAY,KAAK;AAAA,EAC/B,IAAI,MAAM,WAAW,KAAK,MAAM,OAAO,WAAW;AAAA,IAChD,UAAU,qBAAqB;AAAA,EACjC;AAAA,EAEA,SAAS,kBAAkB,aAAa;AAAA,EACxC,MAAM,UAAuB;AAAA,IAC3B,eAAe,UAAU;AAAA,EAC3B;AAAA,EACA,IAAI,WACF,KAAK,YACL,QAAQ,IAAI,iCACZ,QAAQ,IAAI;AAAA,EAEd,KAAK,UAAU;AAAA,IACb,MAAM,WAAU,YAAY;AAAA,IAC5B,WACE,SAAQ,UAAU,SAAS,YAAY,SAAQ,UAAU;AAAA,EAC7D;AAAA,EAEA,IAAI,UAAU;AAAA,IACZ,MAAM,WAAW,YAAY,QAAQ;AAAA,IACrC,IAAI,SAAS,OAAO,OAAO;AAAA,MACzB,MAAM,IAAI,MACR,2DACF;AAAA,IACF;AAAA,IACA,IAAI,SAAS,OAAO,MAAM,IAAI;AAAA,MAC5B,MAAM,IAAI,MACR,sFACF;AAAA,IACF;AAAA,IAEA,QAAQ,yBAAyB,SAAS;AAAA,EAC5C;AAAA,EAEA,MAAM,WACJ,YAAY,6BACZ,SACA,KAAK,KAAK,KAAK,UAAU,QAAQ,IAAI,GAAG,KAAK,OAAO,CACtD;AAAA,EAEA,KAAK,KAAK,OAAO;AAAA,IACf;AAAA,EACF;AAAA,EAEA,IAAI,KAAK,OAAO;AAAA,IACd,QAAQ,MAAM;AAAA,EAChB;AAAA,EACA,QAAQ,KAAK,OAAO,OAAO,KAAK,4BAA2B,CAAC;AAAA,EAC5D,IAAI,YAAY,KAAK,IAAI;AAAA,EACzB,MAAM,aAAa,EAAE,OAAO,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACpD,kBAAkB;AAAA,IAChB,QAAQ;AAAA,IACR,KAAK,YAAY;AAAA,IACjB;AAAA,SACM,UAAS,GAAG,QAAQ;AAAA,MACxB,MAAM,aAAa,WAAW,UAAU,IAAI;AAAA,MAC5C,KAAK,WAAW,WAAW,WAAW,OAAO,WAAW;AAAA,QACtD;AAAA,MACF;AAAA,MACA,YAAY,WAAW;AAAA,MACvB,IAAI,KAAK,OAAO;AAAA,QACd,QAAQ,MAAM;AAAA,MAChB;AAAA,MACA,QAAQ,KACN,OAAO,KAAK,KAAK,sBAAqB,KAAK,QAAQ;AAAA;AAAA,IAAS,IAAI,CAClE;AAAA,MAEA,MAAM,WACJ,YAAY,6BACZ,SACA,KAAK,KAAK,KAAK,UAAU,QAAQ,IAAI,GAAG,KAAK,OAAO,GACpD,KAAK,OACL,IACF;AAAA,MACA,QAAQ,KACN,OAAO,OAAO,KACZ,GAAG,KAAK,QAAQ;AAAA;AAAA,IAAS,8BAC3B,CACF;AAAA;AAAA,EAEJ,CAAC;AAAA,CAEL,EACG,WAAW,kBAAkB,EAC7B,KAAK,GAAG,EACR,cAAc,GAAG,CAAC,EAClB,OAAO,EACP,MAAM;",
8
- "debugId": "190F4F01CE4319C364756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "F3C67DF0D72FBC3064756E2164756E21",
9
9
  "names": []
10
10
  }