@t4h.framework/fs 0.7.0 → 0.8.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.
- package/.ai/skills/framework-fs/SKILL.md +20 -4
- package/.ai/skills/framework-fs-write/SKILL.md +242 -0
- package/CHANGELOG.md +84 -0
- package/LICENSE +21 -0
- package/README.md +36 -2
- package/dist/FileSystemClaim.d.ts +1 -1
- package/dist/FileSystemClaim.d.ts.map +1 -1
- package/dist/FileSystemClaim.js.map +1 -1
- package/dist/activities/FileJoinActivity.d.ts.map +1 -1
- package/dist/activities/FileJoinActivity.js +2 -1
- package/dist/activities/FileJoinActivity.js.map +1 -1
- package/dist/activities/FileWriteActivity.d.ts +20 -0
- package/dist/activities/FileWriteActivity.d.ts.map +1 -0
- package/dist/activities/FileWriteActivity.js +26 -0
- package/dist/activities/FileWriteActivity.js.map +1 -0
- package/dist/fs.d.ts +1 -0
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +1 -0
- package/dist/fs.js.map +1 -1
- package/package.json +3 -3
- package/dist/activities/__tests__/FileJoinActivity.spec.d.ts +0 -2
- package/dist/activities/__tests__/FileJoinActivity.spec.d.ts.map +0 -1
- package/dist/activities/__tests__/FileJoinActivity.spec.js +0 -323
- package/dist/activities/__tests__/FileJoinActivity.spec.js.map +0 -1
- package/dist/activities/__tests__/FileReadActivity.spec.d.ts +0 -2
- package/dist/activities/__tests__/FileReadActivity.spec.d.ts.map +0 -1
- package/dist/activities/__tests__/FileReadActivity.spec.js +0 -120
- package/dist/activities/__tests__/FileReadActivity.spec.js.map +0 -1
- package/dist/activities/__tests__/FileSplitActivity.spec.d.ts +0 -2
- package/dist/activities/__tests__/FileSplitActivity.spec.d.ts.map +0 -1
- package/dist/activities/__tests__/FileSplitActivity.spec.js +0 -170
- package/dist/activities/__tests__/FileSplitActivity.spec.js.map +0 -1
- package/dist/helpers/__tests__/byte-delimiter-scanner.spec.d.ts +0 -2
- package/dist/helpers/__tests__/byte-delimiter-scanner.spec.d.ts.map +0 -1
- package/dist/helpers/__tests__/byte-delimiter-scanner.spec.js +0 -196
- package/dist/helpers/__tests__/byte-delimiter-scanner.spec.js.map +0 -1
|
@@ -4,6 +4,7 @@ description: >-
|
|
|
4
4
|
Guides correct use of @t4h.framework/fs in T4H Framework workflows: the
|
|
5
5
|
FileSystemClaim abstraction that the package activities (http, jsx) use to
|
|
6
6
|
read/write files, the Binary result workflows consume, and runtime providers.
|
|
7
|
+
A workflow never implements Binary itself — see the framework-fs-write skill.
|
|
7
8
|
Use when a workflow orchestrates file-backed package activities, consuming
|
|
8
9
|
Binary results, mocking FileSystemClaim in workflow tests, registering fs
|
|
9
10
|
claim providers, or debugging missing fs provider errors.
|
|
@@ -28,6 +29,8 @@ import {
|
|
|
28
29
|
split, Split, FileSplitActivity, type FileSplitOptions,
|
|
29
30
|
join, FileJoinActivity, type FileJoinOptions, type FileJoinWhere,
|
|
30
31
|
read, FileReadActivity, type FileReadOptions,
|
|
32
|
+
// turn workflow content into a Binary — see the framework-fs-write skill
|
|
33
|
+
write, FileWriteActivity, type FileWriteOptions,
|
|
31
34
|
ByteDelimiterScanner, type FileSplitDelimiter, type ByteRange, type ByteTrim,
|
|
32
35
|
} from '@t4h.framework/fs'
|
|
33
36
|
```
|
|
@@ -46,6 +49,7 @@ export abstract class FileSystemClaim {
|
|
|
46
49
|
public abstract write(
|
|
47
50
|
path: string,
|
|
48
51
|
readable: Readable | Buffer,
|
|
52
|
+
contentType?: string,
|
|
49
53
|
): Binary | Promise<Binary>
|
|
50
54
|
|
|
51
55
|
public abstract read(path: string): Binary | Promise<Binary>
|
|
@@ -60,7 +64,7 @@ export abstract class FileSystemClaim {
|
|
|
60
64
|
|
|
61
65
|
| Method | Purpose |
|
|
62
66
|
|--------|---------|
|
|
63
|
-
| `write(path, readable)` | Persist stream or buffer at `path`; return a `Binary` handle (metadata + `stream()`). |
|
|
67
|
+
| `write(path, readable, contentType?)` | Persist stream or buffer at `path`; return a `Binary` handle (metadata + `stream()`). When `contentType` is omitted, infer it from the path. |
|
|
64
68
|
| `read(path)` | Load an existing file at `path`; return a `Binary` handle. |
|
|
65
69
|
| `slice(binary, range, encoding?)` | A view over a byte range of an existing binary, **without copying data**. When `encoding` is set, the runtime hydrates the slice as a decoded string instead of a binary — this is how `split` children receive plain strings. Implementations must **compose ranges**: slicing a slice is relative to it, and the stored range is absolute against the underlying file. |
|
|
66
70
|
|
|
@@ -96,9 +100,15 @@ read the resulting `Binary` (e.g. `await res.body.json()` / `text()`). Your only
|
|
|
96
100
|
responsibility is that the runtime **registers a provider** (below). See
|
|
97
101
|
**Known consumers** for which package primitives to orchestrate.
|
|
98
102
|
|
|
99
|
-
This package's own workflow-facing primitives are `split`, `join
|
|
103
|
+
This package's own workflow-facing primitives are `split`, `join`, `read`
|
|
100
104
|
(small byte windows — headers, trailers — hydrated into the workflow as a
|
|
101
|
-
string, capped at 1 MiB)
|
|
105
|
+
string, capped at 1 MiB) and `write` (content produced in the workflow turned
|
|
106
|
+
into a file). See the `framework-fs-split` and `framework-fs-write` skills.
|
|
107
|
+
|
|
108
|
+
**A workflow never implements `Binary`.** Every `Binary` comes from the
|
|
109
|
+
framework — an HTTP response body, `sftp.get`, `write`, `join`. A class holding
|
|
110
|
+
bytes in memory cannot be persisted, and every primitive it is handed to
|
|
111
|
+
persists its input. See the `framework-fs-write` skill.
|
|
102
112
|
|
|
103
113
|
---
|
|
104
114
|
|
|
@@ -135,6 +145,9 @@ Test the **workflow** with `TestWorkflowEnvironment` from
|
|
|
135
145
|
claims the triggered activities need, e.g. `HttpClientRequestClaim` for an HTTP
|
|
136
146
|
call). See the **framework-workflow-testing** skill for the harness API.
|
|
137
147
|
|
|
148
|
+
Subclassing `Binary` is legitimate **only here**, in a test double standing in
|
|
149
|
+
for the claim — never in workflow or App code.
|
|
150
|
+
|
|
138
151
|
```typescript
|
|
139
152
|
import { Readable } from 'node:stream'
|
|
140
153
|
import { Binary } from '@t4h.framework/core'
|
|
@@ -180,7 +193,9 @@ Assert `mockWrite` was called with the expected path and body when relevant.
|
|
|
180
193
|
|
|
181
194
|
1. **Extend** `FileSystemClaim` from `@t4h.framework/fs`.
|
|
182
195
|
2. **Return** a `Binary` subclass (or core-compatible `Binary`) from `write` and `read` with correct `contentType`, `contentLength`, and `stream()`.
|
|
183
|
-
3. **Accept** `Readable | Buffer` in `write`
|
|
196
|
+
3. **Accept** `Readable | Buffer` and the optional `contentType` in `write`
|
|
197
|
+
(match the abstract signature), falling back to inferring the content type
|
|
198
|
+
from the path when it is omitted.
|
|
184
199
|
4. **Register** `{ provide: FileSystemClaim, value: new YourImpl() }` in the runtime (tests use `mockClaim(FileSystemClaim, ...)` instead).
|
|
185
200
|
5. **Keep paths deterministic** when activities replay — unpredictable temp paths are fine if only `Binary` metadata is serialized and replay re-executes `write`; know your serializer/replay story if `path` is persisted.
|
|
186
201
|
|
|
@@ -206,6 +221,7 @@ Assert `mockWrite` was called with the expected path and body when relevant.
|
|
|
206
221
|
## Related skills
|
|
207
222
|
|
|
208
223
|
- `framework-fs-split` — `split`/`join`: fan a file out into a batch of workflows and fold the results back into a file.
|
|
224
|
+
- `framework-fs-write` — `write`: turn workflow content into a `Binary`, and why an App must never implement `Binary`.
|
|
209
225
|
- `framework-core` — `Claim`, `Binary`, and the `TestWorkflowEnvironment` testing harness.
|
|
210
226
|
- `framework-http` — HTTP activities that persist bodies via `FileSystemClaim`.
|
|
211
227
|
- `framework-jsx` — render activities that write/read via `fs`.
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: framework-fs-write
|
|
3
|
+
description: >-
|
|
4
|
+
Guides the use of `write` from @t4h.framework/fs — the only supported way to
|
|
5
|
+
turn content produced inside a workflow (a JSON string, a CSV, a positional
|
|
6
|
+
return file, a Buffer) into a `Binary` that other primitives accept. Use
|
|
7
|
+
whenever a workflow must upload, send or save content it built itself:
|
|
8
|
+
`sftp.put`/`sftp.append` with generated content, an HTTP request carrying a
|
|
9
|
+
file, persisting a report, or when the user mentions creating/building a
|
|
10
|
+
Binary, converting a string or Buffer to a Binary, "stringToBinary",
|
|
11
|
+
"BufferBinary", or hits `Unsupported binary instance`. A workflow must NEVER
|
|
12
|
+
implement its own `Binary` subclass — this skill explains why and what to do
|
|
13
|
+
instead.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# `write` — turn workflow content into a `Binary`
|
|
17
|
+
|
|
18
|
+
Every file primitive in the framework speaks `Binary`: `sftp.put`,
|
|
19
|
+
`sftp.append`, `split`, `join`, `pdf`, HTTP bodies. A `Binary` is a
|
|
20
|
+
**reference** to stored content, not the bytes themselves.
|
|
21
|
+
|
|
22
|
+
`write` is what produces one from content your workflow built:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { write } from '@t4h.framework/fs'
|
|
26
|
+
|
|
27
|
+
const file = await write(JSON.stringify(state, null, 2), {
|
|
28
|
+
contentType: 'application/json',
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
await sftp.put('/out/state.json', file)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Package path: `framework/packages/fs`. Import only from the package root.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Never implement `Binary` yourself
|
|
39
|
+
|
|
40
|
+
This is the rule this skill exists to enforce:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// ❌ NEVER — this class cannot be persisted
|
|
44
|
+
class BufferBinary extends Binary {
|
|
45
|
+
constructor(
|
|
46
|
+
private readonly content: Buffer,
|
|
47
|
+
readonly contentType = '...',
|
|
48
|
+
) {
|
|
49
|
+
super()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get contentLength() {
|
|
53
|
+
return this.content.length
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
stream() {
|
|
57
|
+
return Readable.from(this.content)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
await sftp.put('/out/state.json', new BufferBinary(Buffer.from(json)))
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// ✅ ALWAYS
|
|
66
|
+
await sftp.put(
|
|
67
|
+
'/out/state.json',
|
|
68
|
+
await write(json, {
|
|
69
|
+
contentType: 'application/json',
|
|
70
|
+
}),
|
|
71
|
+
)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Why a custom `Binary` cannot work
|
|
75
|
+
|
|
76
|
+
A workflow is **durable**: the body replays, and each activity is persisted
|
|
77
|
+
before it runs. When you pass a value to a primitive, that value becomes the
|
|
78
|
+
activity **input**, and the input is serialized to storage.
|
|
79
|
+
|
|
80
|
+
A `Binary` holding bytes in memory has nothing to serialize into — the buffer
|
|
81
|
+
lives in the process that built it, and the activity may run in another
|
|
82
|
+
process, minutes later, after a replay. The runtime therefore has to spool the
|
|
83
|
+
content somewhere before the activity can be persisted at all.
|
|
84
|
+
|
|
85
|
+
Symptoms of doing it by hand:
|
|
86
|
+
|
|
87
|
+
- `TypeError: Unsupported binary instance` when the activity input is
|
|
88
|
+
serialized, on older runtimes;
|
|
89
|
+
- the activity is never persisted, the transaction rolls back, and the message
|
|
90
|
+
ends up in the dead letter queue after the retries — the run stops mid-way
|
|
91
|
+
with no obvious error in the workflow itself;
|
|
92
|
+
- it may still "work" locally, because the dev server keeps values in memory
|
|
93
|
+
and never crosses a process boundary. **Passing locally proves nothing here.**
|
|
94
|
+
|
|
95
|
+
Current runtimes spool an unknown `Binary` to storage instead of failing, so a
|
|
96
|
+
hand-rolled class may survive — but it pays a hidden copy, loses the content
|
|
97
|
+
type you meant to set, and depends on runtime-version behavior. `write` is the
|
|
98
|
+
contract.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## API
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
function write(
|
|
106
|
+
content: string | Buffer,
|
|
107
|
+
options?: FileWriteOptions,
|
|
108
|
+
): Promise<Binary>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
| Option | Type | Required | Purpose |
|
|
112
|
+
| ------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
113
|
+
| `contentType` | `string` | No | Content type stored with the file — `'application/json'`, `'text/csv'`, … Defaults to what the filename extension implies, then `application/octet-stream`. |
|
|
114
|
+
| `filename` | `string` | No | Name the file is stored under. Defaults to the activity id. |
|
|
115
|
+
| `encoding` | `BufferEncoding` | No | How a **string** `content` is encoded. Defaults to `'utf8'`. Ignored for a `Buffer`, which always travels as base64. |
|
|
116
|
+
|
|
117
|
+
`write` is a durable activity: on replay the content is **not** written again;
|
|
118
|
+
the recorded `Binary` is returned.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## When to use it
|
|
123
|
+
|
|
124
|
+
| Situation | Use |
|
|
125
|
+
| ----------------------------------------------------------------------------- | ----------------------------------------------- |
|
|
126
|
+
| Send content the workflow built (JSON, CSV, positional file) over SFTP/HTTP | `write` |
|
|
127
|
+
| Read a small window of an existing file into the workflow | [`read`](./read) — see **framework-fs-split** |
|
|
128
|
+
| Fan a large file out into one workflow per record | `split` — see **framework-fs-split** |
|
|
129
|
+
| Fold a finished batch back into a file | `join` — see **framework-fs-split** |
|
|
130
|
+
| Content already is a `Binary` (HTTP response body, `sftp.get`, `join` result) | pass it straight through — do not re-`write` it |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Size matters: keep content bounded
|
|
135
|
+
|
|
136
|
+
`write` takes content **in workflow memory**, so it is bounded by what the
|
|
137
|
+
workflow can reasonably hold — a state file, a report, a return file. It is not
|
|
138
|
+
the tool for gigabyte outputs.
|
|
139
|
+
|
|
140
|
+
To build a large file out of many records, use `join` over a batch: it streams
|
|
141
|
+
results one at a time into storage, and nothing but the resulting `Binary`
|
|
142
|
+
reaches the workflow.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Patterns
|
|
147
|
+
|
|
148
|
+
### A) Write then upload
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
const csv = await write(rows.map(toCsvLine).join('\n'), {
|
|
152
|
+
contentType: 'text/csv',
|
|
153
|
+
filename: `report-${input.date}.csv`,
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
await sftp.put(`/out/report-${input.date}.csv`, csv)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### B) Write once, use twice
|
|
160
|
+
|
|
161
|
+
The same `Binary` can be handed to more than one primitive — it is a reference,
|
|
162
|
+
so nothing is copied and nothing is re-uploaded:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
const file = await write(json, { contentType: 'application/json' })
|
|
166
|
+
|
|
167
|
+
await sftp.put(`${path}.tmp`, file)
|
|
168
|
+
await sftp.put(path, file)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Note that a hand-rolled `Binary` backed by a single-use stream would break on
|
|
172
|
+
the second call — another reason not to build one.
|
|
173
|
+
|
|
174
|
+
### C) Binary content
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
const pdfBytes: Buffer = await buildPdf()
|
|
178
|
+
|
|
179
|
+
await sftp.put(
|
|
180
|
+
'/out/invoice.pdf',
|
|
181
|
+
await write(pdfBytes, {
|
|
182
|
+
contentType: 'application/pdf',
|
|
183
|
+
}),
|
|
184
|
+
)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Testing
|
|
190
|
+
|
|
191
|
+
`write` goes through `FileSystemClaim.write`, so mock that claim like any
|
|
192
|
+
other. See the **framework-workflow-testing** skill for the harness API.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { TestWorkflowEnvironment, mockClaim } from '@t4h.framework/core/testing'
|
|
196
|
+
import { FileSystemClaim } from '@t4h.framework/fs'
|
|
197
|
+
|
|
198
|
+
// replay runs the workflow twice — return a fresh Binary per call
|
|
199
|
+
const write = vi
|
|
200
|
+
.fn()
|
|
201
|
+
.mockImplementation(
|
|
202
|
+
async (path, content, contentType) =>
|
|
203
|
+
new MockBinary(
|
|
204
|
+
Buffer.isBuffer(content) ? content : await toBuffer(content),
|
|
205
|
+
contentType,
|
|
206
|
+
),
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
await env.execute(workflow, input, {
|
|
210
|
+
claims: [
|
|
211
|
+
mockClaim(FileSystemClaim, { write, read: vi.fn(), slice: vi.fn() }),
|
|
212
|
+
],
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
expect(write).toHaveBeenCalledWith('report.csv', expect.any(Buffer), 'text/csv')
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Anti-patterns
|
|
221
|
+
|
|
222
|
+
- **Declaring a class that extends `Binary`** in an App. There is no valid
|
|
223
|
+
reason to; use `write`.
|
|
224
|
+
- Helper functions like `stringToBinary(value)` that wrap content in a custom
|
|
225
|
+
class — replace the implementation with `write`, keeping the helper name if
|
|
226
|
+
it reads well.
|
|
227
|
+
- `write`-ing a value that already is a `Binary` (an HTTP response body, a
|
|
228
|
+
`sftp.get` result, a `join` output) — that copies a file to obtain a
|
|
229
|
+
reference you already had.
|
|
230
|
+
- Building a large file by concatenating records in memory and calling `write`
|
|
231
|
+
once — use `split`/`join` instead.
|
|
232
|
+
- Relying on the filename extension to set the content type when the consumer
|
|
233
|
+
cares about it — pass `contentType` explicitly.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Related skills
|
|
238
|
+
|
|
239
|
+
- `framework-fs` — the `FileSystemClaim` contract and runtime providers.
|
|
240
|
+
- `framework-fs-split` — `read`/`split`/`join`: windows, fan-out and fold.
|
|
241
|
+
- `framework-sftp` — `sftp.put`/`append`, the most common consumer of `write`.
|
|
242
|
+
- `framework-workflow-creation` — the rules a workflow body must follow.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# @t4h.framework/fs
|
|
2
|
+
|
|
3
|
+
## 0.8.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#152](https://github.com/tech4humans-brasil/framework/pull/152) [`e0f3f27`](https://github.com/tech4humans-brasil/framework/commit/e0f3f27bc3954e4f06604114dfbc0057f98d6e58) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - Fix import of sift create query tester
|
|
8
|
+
|
|
9
|
+
## 0.8.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [`8c56f76`](https://github.com/tech4humans-brasil/framework/commit/8c56f7697390a1ea966d1e91ff5f35ce5751a0d7) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - feat: write in-memory content to durable storage from a workflow
|
|
14
|
+
|
|
15
|
+
There was no supported way to turn a string or a Buffer into a `Binary` inside
|
|
16
|
+
a workflow — every `Binary` came from an existing file (`http` response,
|
|
17
|
+
`sftp.get`, `split`, `join`). Anyone needing to upload computed content had to
|
|
18
|
+
implement `Binary` by hand, and such an instance can never be persisted, so the
|
|
19
|
+
activity carrying it failed to serialize.
|
|
20
|
+
|
|
21
|
+
`write(content, options?)` covers that gap: it pushes an activity that stores
|
|
22
|
+
the content through the `FileSystemClaim` and returns a `Binary` that survives
|
|
23
|
+
replay.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
const file = await write(JSON.stringify(data), {
|
|
27
|
+
contentType: 'application/json',
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
await sftp.put('/out/data.json', file)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`FileSystemClaim.write` takes an optional `contentType` — until now the content
|
|
34
|
+
type was always inferred from the file extension.
|
|
35
|
+
|
|
36
|
+
The dev codec no longer diverges from the runtime one: its binary kind used to
|
|
37
|
+
match only `DevFileBinary`, so a hand-written `Binary` was silently serialized
|
|
38
|
+
as a plain object locally and blew up once deployed. It now matches any
|
|
39
|
+
`Binary` and spools unknown ones to disk, the same way the runtime spools them
|
|
40
|
+
to the file storage.
|
|
41
|
+
|
|
42
|
+
- [`8c56f76`](https://github.com/tech4humans-brasil/framework/commit/8c56f7697390a1ea966d1e91ff5f35ce5751a0d7) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - Adds FS write activity
|
|
43
|
+
|
|
44
|
+
## 0.7.0
|
|
45
|
+
|
|
46
|
+
### Minor Changes
|
|
47
|
+
|
|
48
|
+
- Adds support to read file ([#109](https://github.com/tech4humans-brasil/framework/pull/109))
|
|
49
|
+
|
|
50
|
+
## 0.6.0
|
|
51
|
+
|
|
52
|
+
### Minor Changes
|
|
53
|
+
|
|
54
|
+
- Adds activity to split and join binary ([#100](https://github.com/tech4humans-brasil/framework/pull/100))
|
|
55
|
+
|
|
56
|
+
## 0.5.0
|
|
57
|
+
|
|
58
|
+
### Patch Changes
|
|
59
|
+
|
|
60
|
+
- Update skills ([`6d7e7bc`](https://github.com/tech4humans-brasil/framework/commit/6d7e7bca0c780a9c53a0c9e5aa0a865c5af67959))
|
|
61
|
+
|
|
62
|
+
## 0.4.0
|
|
63
|
+
|
|
64
|
+
### Patch Changes
|
|
65
|
+
|
|
66
|
+
- Internal dependency updates
|
|
67
|
+
|
|
68
|
+
## 0.3.0
|
|
69
|
+
|
|
70
|
+
### Minor Changes
|
|
71
|
+
|
|
72
|
+
- Adds fs package ([`538c9bd`](https://github.com/tech4humans-brasil/framework/commit/538c9bd5c49031ceb94ef8d6c513f6ffc9c848c5))
|
|
73
|
+
- Adds support to buffer in fs write package ([`476f9f0`](https://github.com/tech4humans-brasil/framework/commit/476f9f08a7b379a3361e42f8577078462276210b))
|
|
74
|
+
- Adds .ai/skills in packages ([#88](https://github.com/tech4humans-brasil/framework/pull/88))
|
|
75
|
+
|
|
76
|
+
### Patch Changes
|
|
77
|
+
|
|
78
|
+
- Remove activity prefix from file system claim class name ([`d257bd1`](https://github.com/tech4humans-brasil/framework/commit/d257bd177d477a56a897ba862a0be1f50531c633))
|
|
79
|
+
- Adds github workflow to run, build, tests and lint ([#18](https://github.com/tech4humans-brasil/framework/pull/18))
|
|
80
|
+
- Adds readme ([`3a55794`](https://github.com/tech4humans-brasil/framework/commit/3a557942769fa022b9a39504046d22b0083e734f))
|
|
81
|
+
- Update package metadata and author information across multiple packages ([`2ca73df`](https://github.com/tech4humans-brasil/framework/commit/2ca73df42dc63c86ed44717b50d5402fca45b4e7))
|
|
82
|
+
- Improve repository info ([`1fad92d`](https://github.com/tech4humans-brasil/framework/commit/1fad92d959b804189fd1486d047115995ac81eb0))
|
|
83
|
+
- Fix resolve module resolution issues in check-types ([`c97a0d2`](https://github.com/tech4humans-brasil/framework/commit/c97a0d2747f38e561cc5c7d592b20de0459bc1ee))
|
|
84
|
+
- Update package dependencies across multiple packages ([`8b4fc1d`](https://github.com/tech4humans-brasil/framework/commit/8b4fc1d0e92d6bd880ddf4c8119fb68c49c53760))
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Tech for humans
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
File system claim for reading and writing files within activities, plus the
|
|
4
4
|
workflow-facing file activities: `split` fans a large file out into one child
|
|
5
5
|
workflow per slice, `join` folds the batch results back into a single file,
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
`read` brings a small byte window (a header, a trailer) into the workflow as a
|
|
7
|
+
string, and `write` turns content the workflow produced into a file.
|
|
8
8
|
|
|
9
9
|
## Claim
|
|
10
10
|
|
|
@@ -23,6 +23,7 @@ abstract class FileSystemClaim {
|
|
|
23
23
|
public abstract write(
|
|
24
24
|
path: string,
|
|
25
25
|
readable: Readable | Buffer,
|
|
26
|
+
contentType?: string,
|
|
26
27
|
): Binary | Promise<Binary>
|
|
27
28
|
public abstract read(path: string): Binary | Promise<Binary>
|
|
28
29
|
|
|
@@ -107,6 +108,39 @@ Reading a slice is relative to the slice: `read(slice, { range: { start: 0,
|
|
|
107
108
|
end: 10 } })` returns the first 10 bytes of the slice, not of the underlying
|
|
108
109
|
file — slice ranges compose.
|
|
109
110
|
|
|
111
|
+
## File write
|
|
112
|
+
|
|
113
|
+
### write
|
|
114
|
+
|
|
115
|
+
Stores content produced inside the workflow and returns its `Binary` — the only
|
|
116
|
+
supported way to obtain a `Binary` from a string or a `Buffer`:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { write } from '@t4h.framework/fs'
|
|
120
|
+
|
|
121
|
+
const file = await write(JSON.stringify(state, null, 2), {
|
|
122
|
+
contentType: 'application/json',
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
await sftp.put('/out/state.json', file)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Options: `contentType` (default: inferred from the filename, then
|
|
129
|
+
`application/octet-stream`), `filename` (default: the activity id) and
|
|
130
|
+
`encoding` for a string content (default `'utf8'`; a `Buffer` always travels as
|
|
131
|
+
base64).
|
|
132
|
+
|
|
133
|
+
**Never implement `Binary` in an App.** Passing a value to a primitive makes it
|
|
134
|
+
the input of a durable activity, and that input is serialized to storage before
|
|
135
|
+
the activity runs — a `Binary` holding bytes in memory has nothing to serialize
|
|
136
|
+
into, and the activity may run in another process after a replay. A hand-rolled
|
|
137
|
+
class can pass locally (the dev server keeps values in memory) and fail once
|
|
138
|
+
deployed.
|
|
139
|
+
|
|
140
|
+
`write` takes content already in workflow memory — a state file, a report, a
|
|
141
|
+
return file. To build a large file out of many records, use `split` + `join`,
|
|
142
|
+
which stream through storage.
|
|
143
|
+
|
|
110
144
|
## File split
|
|
111
145
|
|
|
112
146
|
### split
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Readable } from 'node:stream';
|
|
2
2
|
import type { Binary } from '@t4h.framework/core';
|
|
3
3
|
export declare abstract class FileSystemClaim {
|
|
4
|
-
abstract write(path: string, readable: Readable | Buffer): Binary | Promise<Binary>;
|
|
4
|
+
abstract write(path: string, readable: Readable | Buffer, contentType?: string): Binary | Promise<Binary>;
|
|
5
5
|
abstract read(path: string): Binary | Promise<Binary>;
|
|
6
6
|
abstract slice(binary: Binary, range: {
|
|
7
7
|
start: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSystemClaim.d.ts","sourceRoot":"","sources":["../src/FileSystemClaim.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,8BAAsB,eAAe;aACnB,KAAK,CACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"FileSystemClaim.d.ts","sourceRoot":"","sources":["../src/FileSystemClaim.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,8BAAsB,eAAe;aACnB,KAAK,CACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAC3B,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;aAEX,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;aAE5C,KAAK,CACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EACrC,QAAQ,CAAC,EAAE,cAAc,GACxB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAC5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSystemClaim.js","sourceRoot":"","sources":["../src/FileSystemClaim.ts"],"names":[],"mappings":"AAIA,MAAM,OAAgB,eAAe;
|
|
1
|
+
{"version":3,"file":"FileSystemClaim.js","sourceRoot":"","sources":["../src/FileSystemClaim.ts"],"names":[],"mappings":"AAIA,MAAM,OAAgB,eAAe;CAcpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileJoinActivity.d.ts","sourceRoot":"","sources":["../../src/activities/FileJoinActivity.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,MAAM,EAGX,KAAK,YAAY,EACjB,YAAY,EAGZ,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAA;AAK5B,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"FileJoinActivity.d.ts","sourceRoot":"","sources":["../../src/activities/FileJoinActivity.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ import { OPERATIONS } from '../constants/operations.js';
|
|
|
6
6
|
import { FileSystemClaim } from '../FileSystemClaim.js';
|
|
7
7
|
import { CSV } from '../helpers/CSV.js';
|
|
8
8
|
import { assertWhereSerializable } from '../tools/assert-where-serializable.js';
|
|
9
|
+
const { createQueryTester } = sift;
|
|
9
10
|
const extensions = {
|
|
10
11
|
lines: 'txt',
|
|
11
12
|
entries: 'ndjson',
|
|
@@ -32,7 +33,7 @@ export class FileJoinActivity extends SyncActivity {
|
|
|
32
33
|
if (!options.status && options.format === 'entries')
|
|
33
34
|
statuses.add('rejected');
|
|
34
35
|
const matches = options.where &&
|
|
35
|
-
|
|
36
|
+
createQueryTester(options.where, {
|
|
36
37
|
operations: OPERATIONS,
|
|
37
38
|
});
|
|
38
39
|
await this.writeHeader(options, write);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileJoinActivity.js","sourceRoot":"","sources":["../../src/activities/FileJoinActivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,EAEL,KAAK,EACL,OAAO,EAEP,YAAY,EACZ,kBAAkB,GAGnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;
|
|
1
|
+
{"version":3,"file":"FileJoinActivity.js","sourceRoot":"","sources":["../../src/activities/FileJoinActivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,EAEL,KAAK,EACL,OAAO,EAEP,YAAY,EACZ,kBAAkB,GAGnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAE/E,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAA;AAiElC,MAAM,UAAU,GAA8C;IAC5D,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,QAAQ;IACjB,GAAG,EAAE,KAAK;CACX,CAAA;AAED,MAAM,OAAO,gBAAiB,SAAQ,YAKrC;IACkB,MAAM,GAAG,IAAI,KAAK,CAAC;QAClC,EAAE,EAAE,eAAe;QACnB,KAAK,EAAE,kBAAkB;KAC1B,CAAC,CAAA;IAEK,OAAO,CACZ,KAAuB,EACvB,OAAwB;QAExB,IAAI,OAAO,CAAC,KAAK;YAAE,uBAAuB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAElE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,CAAA;IACrC,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAyB;QACxD,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAA;QAEhC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAClC,QAAQ,IAAI,CAAC,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAC/C,MAAM,CACP,CAAA;QAED,MAAM,KAAK,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;YACnC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACtD,CAAC,CAAA;QAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAiB,OAAO,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC,CAAA;QAEzE,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;YACjD,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QAE1B,MAAM,OAAO,GACX,OAAO,CAAC,KAAK;YACb,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE;gBAC/B,UAAU,EAAE,UAAU;aACvB,CAAC,CAAA;QAEJ,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QAEtC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;gBAAE,SAAQ;YAEzC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;gBAAE,SAAQ;YAE/C,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAA;QAC1C,CAAC;QAED,MAAM,CAAC,GAAG,EAAE,CAAA;QAEZ,OAAO,MAAM,OAAO,CAAA;IACtB,CAAC;IAEM,QAAQ,CAAC,MAAc;QAC5B,OAAO,MAAM,CAAA;IACf,CAAC;IAEO,KAAK,CAAC,WAAW,CACvB,OAAwB,EACxB,KAAsC;QAEtC,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,IAAI,OAAO,CAAC,MAAM;YAC9C,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAA;QAE3D,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK;YACtD,MAAM,KAAK,CACT,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAChE,CAAA;IACL,CAAC;IAEO,MAAM,CAAC,KAA0B,EAAE,OAAwB;QACjE,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;QAErE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK;YAC1B,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE;gBAC/C,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B,CAAC,CAAA;QAEJ,MAAM,KAAK,GACT,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;YAC9B,CAAC,CAAC,KAAK,CAAC,MAAM;YACd,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAElC,OAAO,KAAK,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,CAAA;IAC5C,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,KAAuB,EACvB,OAAiC;IAEjC,OAAO,MAAM,OAAO,CAAC,UAAU,CAC7B,gBAAgB,EAChB,KAAK,EACL,OAA0B,CAC3B,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Binary, SyncActivity } from '@t4h.framework/core';
|
|
2
|
+
export type FileWriteOptions = {
|
|
3
|
+
filename?: string;
|
|
4
|
+
contentType?: string;
|
|
5
|
+
encoding?: BufferEncoding;
|
|
6
|
+
};
|
|
7
|
+
export type FileWriteActivityInput = {
|
|
8
|
+
content: string;
|
|
9
|
+
encoding: BufferEncoding;
|
|
10
|
+
filename: string;
|
|
11
|
+
contentType?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare class FileWriteActivity extends SyncActivity<readonly [content: string | Buffer, options: FileWriteOptions], FileWriteActivityInput, Binary, Binary> {
|
|
14
|
+
private readonly claims;
|
|
15
|
+
toInput(content: string | Buffer, options: FileWriteOptions): FileWriteActivityInput;
|
|
16
|
+
run({ content, encoding, filename, contentType, }: FileWriteActivityInput): Promise<Binary>;
|
|
17
|
+
toOutput(output: Binary): Binary;
|
|
18
|
+
}
|
|
19
|
+
export declare function write(content: string | Buffer, options?: FileWriteOptions): Promise<Binary>;
|
|
20
|
+
//# sourceMappingURL=FileWriteActivity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileWriteActivity.d.ts","sourceRoot":"","sources":["../../src/activities/FileWriteActivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAkB,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAI/E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,cAAc,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,cAAc,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,qBAAa,iBAAkB,SAAQ,YAAY,CACjD,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,EAC9D,sBAAsB,EACtB,MAAM,EACN,MAAM,CACP;IACC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAErB;IAEK,OAAO,CACZ,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,OAAO,EAAE,gBAAgB,GACxB,sBAAsB;IAWZ,GAAG,CAAC,EACf,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,WAAW,GACZ,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAQpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAGxC;AAED,wBAAsB,KAAK,CACzB,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAEjB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Claim, History, SyncActivity } from '@t4h.framework/core';
|
|
2
|
+
import { FileSystemClaim } from '../FileSystemClaim.js';
|
|
3
|
+
export class FileWriteActivity extends SyncActivity {
|
|
4
|
+
claims = new Claim({
|
|
5
|
+
fs: FileSystemClaim,
|
|
6
|
+
});
|
|
7
|
+
toInput(content, options) {
|
|
8
|
+
const isBuffer = Buffer.isBuffer(content);
|
|
9
|
+
return {
|
|
10
|
+
content: isBuffer ? content.toString('base64') : content,
|
|
11
|
+
encoding: isBuffer ? 'base64' : (options.encoding ?? 'utf8'),
|
|
12
|
+
filename: options.filename ?? this.id,
|
|
13
|
+
contentType: options.contentType,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
async run({ content, encoding, filename, contentType, }) {
|
|
17
|
+
return await this.claims.fs.write(filename, Buffer.from(content, encoding), contentType);
|
|
18
|
+
}
|
|
19
|
+
toOutput(output) {
|
|
20
|
+
return output;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function write(content, options = {}) {
|
|
24
|
+
return await History.reconciler(FileWriteActivity, content, options);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=FileWriteActivity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileWriteActivity.js","sourceRoot":"","sources":["../../src/activities/FileWriteActivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAE/E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAevD,MAAM,OAAO,iBAAkB,SAAQ,YAKtC;IACkB,MAAM,GAAG,IAAI,KAAK,CAAC;QAClC,EAAE,EAAE,eAAe;KACpB,CAAC,CAAA;IAEK,OAAO,CACZ,OAAwB,EACxB,OAAyB;QAEzB,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAEzC,OAAO;YACL,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO;YACxD,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC;YAC5D,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAE;YACrC,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAA;IACH,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,EACf,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,WAAW,GACY;QACvB,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAC/B,QAAQ,EACR,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAC9B,WAAW,CACZ,CAAA;IACH,CAAC;IAEM,QAAQ,CAAC,MAAc;QAC5B,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,OAAwB,EACxB,UAA4B,EAAE;IAE9B,OAAO,MAAM,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;AACtE,CAAC"}
|
package/dist/fs.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export * from './FileSystemClaim.js';
|
|
|
2
2
|
export * from './activities/FileJoinActivity.js';
|
|
3
3
|
export * from './activities/FileReadActivity.js';
|
|
4
4
|
export * from './activities/FileSplitActivity.js';
|
|
5
|
+
export * from './activities/FileWriteActivity.js';
|
|
5
6
|
export * from './helpers/byte-delimiter-scanner.js';
|
|
6
7
|
//# sourceMappingURL=fs.d.ts.map
|
package/dist/fs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,kCAAkC,CAAA;AAChD,cAAc,mCAAmC,CAAA;AACjD,cAAc,qCAAqC,CAAA"}
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,kCAAkC,CAAA;AAChD,cAAc,mCAAmC,CAAA;AACjD,cAAc,mCAAmC,CAAA;AACjD,cAAc,qCAAqC,CAAA"}
|
package/dist/fs.js
CHANGED
|
@@ -2,5 +2,6 @@ export * from './FileSystemClaim.js';
|
|
|
2
2
|
export * from './activities/FileJoinActivity.js';
|
|
3
3
|
export * from './activities/FileReadActivity.js';
|
|
4
4
|
export * from './activities/FileSplitActivity.js';
|
|
5
|
+
export * from './activities/FileWriteActivity.js';
|
|
5
6
|
export * from './helpers/byte-delimiter-scanner.js';
|
|
6
7
|
//# sourceMappingURL=fs.js.map
|
package/dist/fs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,kCAAkC,CAAA;AAChD,cAAc,mCAAmC,CAAA;AACjD,cAAc,qCAAqC,CAAA"}
|
|
1
|
+
{"version":3,"file":"fs.js","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,kCAAkC,CAAA;AAChD,cAAc,mCAAmC,CAAA;AACjD,cAAc,mCAAmC,CAAA;AACjD,cAAc,qCAAqC,CAAA"}
|