@orpc/node 2.0.0-beta.25 → 2.0.0-beta.28
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 +37 -76
- package/dist/index.d.mts +111 -2
- package/dist/index.d.ts +111 -2
- package/dist/index.mjs +412 -5
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -75,7 +75,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
75
75
|
|
|
76
76
|
<table>
|
|
77
77
|
<tr>
|
|
78
|
-
<td align="center"><a href="https://screenshotone.com/?ref=orpc" target="_blank" rel="noopener" title="ScreenshotOne.com"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="279" alt="ScreenshotOne.com"/><br />ScreenshotOne.com</a></td>
|
|
78
|
+
<td align="center"><a href="https://screenshotone.com/?ref=orpc" target="_blank" rel="sponsored noopener" title="ScreenshotOne.com"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="279" alt="ScreenshotOne.com"/><br />ScreenshotOne.com</a></td>
|
|
79
79
|
</tr>
|
|
80
80
|
</table>
|
|
81
81
|
|
|
@@ -83,7 +83,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
83
83
|
|
|
84
84
|
<table>
|
|
85
85
|
<tr>
|
|
86
|
-
<td align="center"><a href="https://misskey.io/?ref=orpc" target="_blank" rel="noopener" title="村上さん"><img src="https://avatars.githubusercontent.com/u/37681609?u=0dd4c7e4ba937cbb52b068c55914b1d8164dc0c7&v=4" width="209" alt="村上さん"/><br />村上さん</a></td>
|
|
86
|
+
<td align="center"><a href="https://misskey.io/?ref=orpc" target="_blank" rel="sponsored noopener" title="村上さん"><img src="https://avatars.githubusercontent.com/u/37681609?u=0dd4c7e4ba937cbb52b068c55914b1d8164dc0c7&v=4" width="209" alt="村上さん"/><br />村上さん</a></td>
|
|
87
87
|
</tr>
|
|
88
88
|
</table>
|
|
89
89
|
|
|
@@ -91,7 +91,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
91
91
|
|
|
92
92
|
<table>
|
|
93
93
|
<tr>
|
|
94
|
-
<td align="center"><a href="https://github.com/ln-markets?ref=orpc" target="_blank" rel="noopener" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="167" alt="LN Markets"/><br />LN Markets</a></td>
|
|
94
|
+
<td align="center"><a href="https://github.com/ln-markets?ref=orpc" target="_blank" rel="sponsored noopener" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="167" alt="LN Markets"/><br />LN Markets</a></td>
|
|
95
95
|
</tr>
|
|
96
96
|
</table>
|
|
97
97
|
|
|
@@ -99,24 +99,26 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
99
99
|
|
|
100
100
|
<table>
|
|
101
101
|
<tr>
|
|
102
|
-
<td align="center"><a href="https://github.com/hrmcdonald?ref=orpc" target="_blank" rel="noopener" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="139" alt="Reece McDonald"/><br />Reece McDonald</a></td>
|
|
103
|
-
<td align="center"><a href="https://github.com/
|
|
104
|
-
<td align="center"><a href="https://github.com/
|
|
105
|
-
<td align="center"><a href="https://github.com/
|
|
106
|
-
<td align="center"><a href="https://github.com/
|
|
107
|
-
<td align="center"><a href="https://github.com/
|
|
102
|
+
<td align="center"><a href="https://github.com/hrmcdonald?ref=orpc" target="_blank" rel="sponsored noopener" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="139" alt="Reece McDonald"/><br />Reece McDonald</a></td>
|
|
103
|
+
<td align="center"><a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="sponsored noopener" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&v=4" width="139" alt="あわわわとーにゅ"/><br />あわわわとーにゅ</a></td>
|
|
104
|
+
<td align="center"><a href="https://github.com/nicognaW?ref=orpc" target="_blank" rel="sponsored noopener" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&v=4" width="139" alt="nk"/><br />nk</a></td>
|
|
105
|
+
<td align="center"><a href="https://github.com/supastarter?ref=orpc" target="_blank" rel="sponsored noopener" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="139" alt="supastarter"/><br />supastarter</a></td>
|
|
106
|
+
<td align="center"><a href="https://github.com/divmgl?ref=orpc" target="_blank" rel="sponsored noopener" title="Dexter Miguel"><img src="https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&v=4" width="139" alt="Dexter Miguel"/><br />Dexter Miguel</a></td>
|
|
107
|
+
<td align="center"><a href="https://github.com/herrfugbaum?ref=orpc" target="_blank" rel="sponsored noopener" title="herrfugbaum"><img src="https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&v=4" width="139" alt="herrfugbaum"/><br />herrfugbaum</a></td>
|
|
108
108
|
</tr>
|
|
109
109
|
<tr>
|
|
110
|
-
<td align="center"><a href="https://github.com/
|
|
111
|
-
<td align="center"><a href="https://github.com/
|
|
112
|
-
<td align="center"><a href="https://github.com/
|
|
113
|
-
<td align="center"><a href="https://github.com/
|
|
114
|
-
<td align="center"><a href="https://github.com/
|
|
115
|
-
<td align="center"><a href="https://github.com/
|
|
110
|
+
<td align="center"><a href="https://github.com/ryota-murakami?ref=orpc" target="_blank" rel="sponsored noopener" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&v=4" width="139" alt="Ryota Murakami"/><br />Ryota Murakami</a></td>
|
|
111
|
+
<td align="center"><a href="https://github.com/dcramer?ref=orpc" target="_blank" rel="sponsored noopener" title="David Cramer"><img src="https://avatars.githubusercontent.com/u/23610?v=4" width="139" alt="David Cramer"/><br />David Cramer</a></td>
|
|
112
|
+
<td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="sponsored noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td>
|
|
113
|
+
<td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="sponsored noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td>
|
|
114
|
+
<td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="sponsored noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td>
|
|
115
|
+
<td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="sponsored noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
|
|
116
116
|
</tr>
|
|
117
117
|
<tr>
|
|
118
|
-
<td align="center"><a href="https://github.com/
|
|
119
|
-
<td align="center"><a href="https://github.com/
|
|
118
|
+
<td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="sponsored noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
|
|
119
|
+
<td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="sponsored noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="139" alt="shota"/><br />shota</a></td>
|
|
120
|
+
<td align="center"><a href="https://github.com/ellis-driscoll?ref=orpc" target="_blank" rel="sponsored noopener" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td>
|
|
121
|
+
<td align="center"><a href="https://github.com/hoangbn?ref=orpc" target="_blank" rel="sponsored noopener" title="Hoang Nguyen"><img src="https://avatars.githubusercontent.com/u/38968280?u=c90084c6de65c56facabab7ba13a72a49ddbc3e4&v=4" width="139" alt="Hoang Nguyen"/><br />Hoang Nguyen</a></td>
|
|
120
122
|
</tr>
|
|
121
123
|
</table>
|
|
122
124
|
|
|
@@ -124,72 +126,31 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
124
126
|
|
|
125
127
|
<table>
|
|
126
128
|
<tr>
|
|
127
|
-
<td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td>
|
|
128
|
-
<td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td>
|
|
129
|
-
<td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td>
|
|
130
|
-
<td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&v=4" width="119" alt="soonoo"/><br />soonoo</a></td>
|
|
131
|
-
<td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td>
|
|
132
|
-
<td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&v=4" width="119" alt="Denis"/><br />Denis</a></td>
|
|
133
|
-
<td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
|
|
129
|
+
<td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="sponsored noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td>
|
|
130
|
+
<td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="sponsored noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td>
|
|
131
|
+
<td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="sponsored noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td>
|
|
132
|
+
<td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="sponsored noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&v=4" width="119" alt="soonoo"/><br />soonoo</a></td>
|
|
133
|
+
<td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="sponsored noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td>
|
|
134
|
+
<td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="sponsored noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&v=4" width="119" alt="Denis"/><br />Denis</a></td>
|
|
135
|
+
<td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="sponsored noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
|
|
134
136
|
</tr>
|
|
135
137
|
<tr>
|
|
136
|
-
<td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td>
|
|
137
|
-
<td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&v=4" width="119" alt="Sam"/><br />Sam</a></td>
|
|
138
|
-
<td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&v=4" width="119" alt="Titoine"/><br />Titoine</a></td>
|
|
139
|
-
<td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td>
|
|
140
|
-
<td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td>
|
|
141
|
-
<td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td>
|
|
142
|
-
<td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
|
|
138
|
+
<td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="sponsored noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td>
|
|
139
|
+
<td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="sponsored noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&v=4" width="119" alt="Sam"/><br />Sam</a></td>
|
|
140
|
+
<td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="sponsored noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&v=4" width="119" alt="Titoine"/><br />Titoine</a></td>
|
|
141
|
+
<td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="sponsored noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td>
|
|
142
|
+
<td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="sponsored noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td>
|
|
143
|
+
<td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="sponsored noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td>
|
|
144
|
+
<td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="sponsored noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
|
|
143
145
|
</tr>
|
|
144
146
|
<tr>
|
|
145
|
-
<td align="center"><a href="https://github.com/guyariely?ref=orpc" target="_blank" rel="noopener" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td>
|
|
146
|
-
<td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&v=4" width="119" alt="Alex"/><br />Alex</a></td>
|
|
147
|
-
<td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
|
|
147
|
+
<td align="center"><a href="https://github.com/guyariely?ref=orpc" target="_blank" rel="sponsored noopener" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td>
|
|
148
|
+
<td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="sponsored noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&v=4" width="119" alt="Alex"/><br />Alex</a></td>
|
|
149
|
+
<td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="sponsored noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
|
|
148
150
|
</tr>
|
|
149
151
|
</table>
|
|
150
152
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
<p>
|
|
154
|
-
<a href="https://github.com/MrMaxie?ref=orpc" target="_blank" rel="noopener" title="Maxie"><img src="https://avatars.githubusercontent.com/u/3857836?u=5e6b57973d4385d655663ffdd836e487856f2984&v=4" width="32" height="32" alt="Maxie" /></a>
|
|
155
|
-
<a href="https://github.com/Stijn-Timmer?ref=orpc" target="_blank" rel="noopener" title="Stijn Timmer"><img src="https://avatars.githubusercontent.com/u/100147665?u=106b2c18e9c98a61861b4ee7fc100f5b9906a6c9&v=4" width="32" height="32" alt="Stijn Timmer" /></a>
|
|
156
|
-
<a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="noopener" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&v=4" width="32" height="32" alt="あわわわとーにゅ" /></a>
|
|
157
|
-
<a href="https://github.com/zuplo?ref=orpc" target="_blank" rel="noopener" title="Zuplo"><img src="https://avatars.githubusercontent.com/u/85497839?v=4" width="32" height="32" alt="Zuplo" /></a>
|
|
158
|
-
<a href="https://github.com/motopods?ref=orpc" target="_blank" rel="noopener" title="motopods"><img src="https://avatars.githubusercontent.com/u/58200641?v=4" width="32" height="32" alt="motopods" /></a>
|
|
159
|
-
<a href="https://github.com/franciscohermida?ref=orpc" target="_blank" rel="noopener" title="Francisco Hermida"><img src="https://avatars.githubusercontent.com/u/483242?u=bbcbc80eb9d8781ff401f7dafc3b59cd7bea0561&v=4" width="32" height="32" alt="Francisco Hermida" /></a>
|
|
160
|
-
<a href="https://github.com/theoludwig?ref=orpc" target="_blank" rel="noopener" title="Théo LUDWIG"><img src="https://avatars.githubusercontent.com/u/25207499?u=a6a9653725a2f574c07893748806668e0598cdbe&v=4" width="32" height="32" alt="Théo LUDWIG" /></a>
|
|
161
|
-
<a href="https://github.com/abhay-ramesh?ref=orpc" target="_blank" rel="noopener" title="Abhay Ramesh"><img src="https://avatars.githubusercontent.com/u/66196314?u=c5c2b0327b26606c2efcfaf17046ab18c3d25c57&v=4" width="32" height="32" alt="Abhay Ramesh" /></a>
|
|
162
|
-
<a href="https://github.com/shr-ink?ref=orpc" target="_blank" rel="noopener" title="shr.ink oü"><img src="https://avatars.githubusercontent.com/u/139700438?v=4" width="32" height="32" alt="shr.ink oü" /></a>
|
|
163
|
-
<a href="https://github.com/johngerome?ref=orpc" target="_blank" rel="noopener" title="0x4e32"><img src="https://avatars.githubusercontent.com/u/2002000?u=505e54608466ab53754f702973687b04c6424c1f&v=4" width="32" height="32" alt="0x4e32" /></a>
|
|
164
|
-
<a href="https://github.com/yzuyr?ref=orpc" target="_blank" rel="noopener" title="Ryuz"><img src="https://avatars.githubusercontent.com/u/196539378?u=d38374588d219b6748b16406982f6559411466d4&v=4" width="32" height="32" alt="Ryuz" /></a>
|
|
165
|
-
<a href="https://github.com/happyboy2022?ref=orpc" target="_blank" rel="noopener" title="happyboy"><img src="https://avatars.githubusercontent.com/u/103669586?u=65b49c4b893ed3703909fbb3a7a22313f3f9c121&v=4" width="32" height="32" alt="happyboy" /></a>
|
|
166
|
-
<a href="https://github.com/YiCChi?ref=orpc" target="_blank" rel="noopener" title="yicchi"><img src="https://avatars.githubusercontent.com/u/86967274?u=6c2756f09fe15dd94d572f560e979cd157982852&v=4" width="32" height="32" alt="yicchi" /></a>
|
|
167
|
-
<a href="https://github.com/cloudycotton?ref=orpc" target="_blank" rel="noopener" title="Saksham"><img src="https://avatars.githubusercontent.com/u/168998965?u=9b9634a5aed66a51c1b880663272725b00b92b14&v=4" width="32" height="32" alt="Saksham" /></a>
|
|
168
|
-
<a href="https://github.com/hrynevychroman?ref=orpc" target="_blank" rel="noopener" title="Roman Hrynevych"><img src="https://avatars.githubusercontent.com/u/82209198?u=1a1d111ab3d589855b9cc8a7fefb1b5c6a4fbbaf&v=4" width="32" height="32" alt="Roman Hrynevych" /></a>
|
|
169
|
-
<a href="https://github.com/rokitgg?ref=orpc" target="_blank" rel="noopener" title="rokitg"><img src="https://avatars.githubusercontent.com/u/125133357?u=06c74aefaa2236b06a2e5fba5a5c612339f45912&v=4" width="32" height="32" alt="rokitg" /></a>
|
|
170
|
-
<a href="https://github.com/omarkhatibgg?ref=orpc" target="_blank" rel="noopener" title="Omar Khatib"><img src="https://avatars.githubusercontent.com/u/9054278?u=afbba7331b85c51b8eee4130f5fd31b1017dc919&v=4" width="32" height="32" alt="Omar Khatib" /></a>
|
|
171
|
-
<a href="https://github.com/YuSabo90002?ref=orpc" target="_blank" rel="noopener" title="Yu-Sabo"><img src="https://avatars.githubusercontent.com/u/13120582?v=4" width="32" height="32" alt="Yu-Sabo" /></a>
|
|
172
|
-
<a href="https://github.com/bapspatil?ref=orpc" target="_blank" rel="noopener" title="Bapusaheb Patil"><img src="https://avatars.githubusercontent.com/u/16699418?u=6d9d8e0a64a6f91ca1c4d559c72d931172bdcbbd&v=4" width="32" height="32" alt="Bapusaheb Patil" /></a>
|
|
173
|
-
<a href="https://github.com/ripgrim?ref=orpc" target="_blank" rel="noopener" title="grim"><img src="https://avatars.githubusercontent.com/u/75869731?u=b17c42ec2309552fdb822a86b25a2f99146a4d72&v=4" width="32" height="32" alt="grim" /></a>
|
|
174
|
-
<a href="https://github.com/nelsonlaidev?ref=orpc" target="_blank" rel="noopener" title="Nelson Lai"><img src="https://avatars.githubusercontent.com/u/75498339?u=2fc0e0b95dd184c5ffb744df977cb15a18b60672&v=4" width="32" height="32" alt="Nelson Lai" /></a>
|
|
175
|
-
<a href="https://github.com/nguyenlc1993?ref=orpc" target="_blank" rel="noopener" title="Lê Cao Nguyên"><img src="https://avatars.githubusercontent.com/u/13871971?u=83c8b69d9e35b589c4e1f066cc113b1d9461386f&v=4" width="32" height="32" alt="Lê Cao Nguyên" /></a>
|
|
176
|
-
<a href="https://github.com/wobsoriano?ref=orpc" target="_blank" rel="noopener" title="Robert Soriano"><img src="https://avatars.githubusercontent.com/u/13049130?u=6d72104182e7c9ed25934815313fb69107332111&v=4" width="32" height="32" alt="Robert Soriano" /></a>
|
|
177
|
-
<a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="32" height="32" alt="Andrew Peters" /></a>
|
|
178
|
-
<a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&v=4" width="32" height="32" alt="Ryan Vogel" /></a>
|
|
179
|
-
<a href="https://github.com/SKostyukovich?ref=orpc" target="_blank" rel="noopener" title="SKostyukovich"><img src="https://avatars.githubusercontent.com/u/10700067?v=4" width="32" height="32" alt="SKostyukovich" /></a>
|
|
180
|
-
<a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&v=4" width="32" height="32" alt="Peter Adam" /></a>
|
|
181
|
-
<a href="https://github.com/FabworksHQ?ref=orpc" target="_blank" rel="noopener" title="Fabworks"><img src="https://avatars.githubusercontent.com/u/160179500?v=4" width="32" height="32" alt="Fabworks" /></a>
|
|
182
|
-
<a href="https://github.com/NovakAnton?ref=orpc" target="_blank" rel="noopener" title="Novak Antonijevic"><img src="https://avatars.githubusercontent.com/u/157126729?u=ae49fa22292d55c0434ff0ca008206155b18663b&v=4" width="32" height="32" alt="Novak Antonijevic" /></a>
|
|
183
|
-
<a href="https://github.com/laduniestu?ref=orpc" target="_blank" rel="noopener" title="Laduni Estu Syalwa"><img src="https://avatars.githubusercontent.com/u/44757637?u=a2fc1ea8f7d827a96721176f79d30592d1c48059&v=4" width="32" height="32" alt="Laduni Estu Syalwa" /></a>
|
|
184
|
-
<a href="https://github.com/yukimotochern?ref=orpc" target="_blank" rel="noopener" title="Chen, Zhi-Yuan"><img src="https://avatars.githubusercontent.com/u/20896173?u=945c33fc21725e4d566a0d02afc54b136ca1d67a&v=4" width="32" height="32" alt="Chen, Zhi-Yuan" /></a>
|
|
185
|
-
<a href="https://github.com/illarionvk?ref=orpc" target="_blank" rel="noopener" title="Illarion Koperski"><img src="https://avatars.githubusercontent.com/u/5012724?u=7cfa13652f7ac5fb3c56d880e3eb3fbe40c3ea34&v=4" width="32" height="32" alt="Illarion Koperski" /></a>
|
|
186
|
-
<a href="https://github.com/steelbrain?ref=orpc" target="_blank" rel="noopener" title="Anees Iqbal"><img src="https://avatars.githubusercontent.com/u/4278113?u=22b80b5399eed68ac76cd58b02961b0481f1db11&v=4" width="32" height="32" alt="Anees Iqbal" /></a>
|
|
187
|
-
<a href="https://github.com/Scrumplex?ref=orpc" target="_blank" rel="noopener" title="Sefa Eyeoglu"><img src="https://avatars.githubusercontent.com/u/11587657?u=ab503582165c0bbff0cca47ce31c9450bb1553c9&v=4" width="32" height="32" alt="Sefa Eyeoglu" /></a>
|
|
188
|
-
<a href="https://github.com/nattstack?ref=orpc" target="_blank" rel="noopener" title="natt"><img src="https://avatars.githubusercontent.com/u/31426677?u=fa9dbb8b3e66eb0ea3c88db5dc07f31c8c5418fe&v=4" width="32" height="32" alt="natt" /></a>
|
|
189
|
-
<a href="https://github.com/ChromeGG?ref=orpc" target="_blank" rel="noopener" title="Adam Tkaczyk"><img src="https://avatars.githubusercontent.com/u/39050595?u=a58ca6042a6950e94e6e92442db76ef584279bc0&v=4" width="32" height="32" alt="Adam Tkaczyk" /></a>
|
|
190
|
-
<a href="https://github.com/plancraft?ref=orpc" target="_blank" rel="noopener" title="plancraft"><img src="https://avatars.githubusercontent.com/u/46482287?v=4" width="32" height="32" alt="plancraft" /></a>
|
|
191
|
-
<a href="https://github.com/Nic13Gamer?ref=orpc" target="_blank" rel="noopener" title="Nicholas"><img src="https://avatars.githubusercontent.com/u/54724556?u=56a7ab430ce7a80d648ab6eba051d454a818ed0b&v=4" width="32" height="32" alt="Nicholas" /></a>
|
|
192
|
-
</p>
|
|
153
|
+
With thanks to 37 past sponsors who helped get oRPC here.
|
|
193
154
|
|
|
194
155
|
## References
|
|
195
156
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context } from '@orpc/server';
|
|
2
2
|
import { StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
|
|
3
|
+
import { FilePropertyBag } from 'node:buffer';
|
|
3
4
|
|
|
4
5
|
interface StaticFileHandlerPluginOptions {
|
|
5
6
|
/**
|
|
@@ -126,5 +127,113 @@ declare class StaticFileHandlerPlugin<T extends Context> implements StandardHand
|
|
|
126
127
|
private serve;
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
interface TmpFileUploadHandlerPluginMaxBodySize {
|
|
131
|
+
/**
|
|
132
|
+
* The maximum total size in bytes of request body content that is parsed
|
|
133
|
+
* into memory: JSON, URL-encoded forms, and the plain fields of a multipart
|
|
134
|
+
* body. A larger body rejects the request with `PAYLOAD_TOO_LARGE`. Usually
|
|
135
|
+
* the lowest of the three limits, because this content cannot stream anywhere.
|
|
136
|
+
*/
|
|
137
|
+
memory: number;
|
|
138
|
+
/**
|
|
139
|
+
* The maximum total size in bytes of upload content a request streams into
|
|
140
|
+
* temporary files: file bodies and the file parts of a multipart body
|
|
141
|
+
* combined. A larger body rejects the request with `PAYLOAD_TOO_LARGE`.
|
|
142
|
+
*/
|
|
143
|
+
file: number;
|
|
144
|
+
/**
|
|
145
|
+
* The maximum total size in bytes of a request body that is consumed as a
|
|
146
|
+
* stream: event streams and raw binary streams. Enforced while the stream is
|
|
147
|
+
* consumed, so an oversized stream fails at the reader. Usually the highest
|
|
148
|
+
* of the three limits, because this content is consumed on the fly.
|
|
149
|
+
*/
|
|
150
|
+
stream: number;
|
|
151
|
+
}
|
|
152
|
+
interface TmpFileUploadHandlerPluginOptions {
|
|
153
|
+
/**
|
|
154
|
+
* The directory temporary files are created under. Each request that spools
|
|
155
|
+
* an upload gets its own subdirectory inside it, removed when the request
|
|
156
|
+
* finishes.
|
|
157
|
+
*
|
|
158
|
+
* @default os.tmpdir()
|
|
159
|
+
*/
|
|
160
|
+
tmpDir?: string;
|
|
161
|
+
/**
|
|
162
|
+
* The size limit for each kind of request body. Every kind is required when
|
|
163
|
+
* the option is given, so none is left unbounded by accident; set a kind to
|
|
164
|
+
* `Number.POSITIVE_INFINITY` to deliberately leave it unlimited.
|
|
165
|
+
*
|
|
166
|
+
* @default unlimited for every kind
|
|
167
|
+
*/
|
|
168
|
+
maxBodySize?: TmpFileUploadHandlerPluginMaxBodySize;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* A `File` whose content lives in a temporary file on disk and is read lazily,
|
|
172
|
+
* so it can represent an upload far larger than available memory.
|
|
173
|
+
*
|
|
174
|
+
* @see {@link https://orpc.dev/docs/plugins/tmp-file-upload | Tmp File Upload Plugin}
|
|
175
|
+
*/
|
|
176
|
+
declare class TmpFile extends File {
|
|
177
|
+
/**
|
|
178
|
+
* Absolute path of the temporary file holding this file's content.
|
|
179
|
+
* The file is removed when the request finishes, so move or copy it
|
|
180
|
+
* to keep the content. The `File` reads from this path, so it must
|
|
181
|
+
* not be read after the file is moved or removed.
|
|
182
|
+
*/
|
|
183
|
+
readonly path: string;
|
|
184
|
+
constructor(blob: Blob,
|
|
185
|
+
/**
|
|
186
|
+
* Absolute path of the temporary file holding this file's content.
|
|
187
|
+
* The file is removed when the request finishes, so move or copy it
|
|
188
|
+
* to keep the content. The `File` reads from this path, so it must
|
|
189
|
+
* not be read after the file is moved or removed.
|
|
190
|
+
*/
|
|
191
|
+
path: string, name: string, options?: FilePropertyBag);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Parses file uploads into temporary files instead of memory. Bodies the standard
|
|
195
|
+
* body parser would buffer into an in-memory `File`, and multipart file parts, are
|
|
196
|
+
* streamed to disk and surfaced as lazily read {@link TmpFile} instances, so requests
|
|
197
|
+
* far larger than available memory parse in constant memory. Every other body is left
|
|
198
|
+
* to the standard parser.
|
|
199
|
+
*
|
|
200
|
+
* Request body sizes are limited per content category: memory-parsed, spooled to
|
|
201
|
+
* disk, and streamed. This subsumes the request limit plugin while sizing each
|
|
202
|
+
* kind of body to what it actually costs.
|
|
203
|
+
*
|
|
204
|
+
* @remarks
|
|
205
|
+
* Temporary files are removed when the request finishes. A streaming response body,
|
|
206
|
+
* an event iterator or a raw stream, keeps them alive until it completes, so
|
|
207
|
+
* responses that read the upload while streaming work. Any other response is
|
|
208
|
+
* transmitted after removal, so one that embeds the upload itself, as a `File` or
|
|
209
|
+
* inside `FormData`, needs the content copied or the file moved first.
|
|
210
|
+
*
|
|
211
|
+
* @see {@link https://orpc.dev/docs/plugins/tmp-file-upload | Tmp File Upload Plugin}
|
|
212
|
+
*/
|
|
213
|
+
declare class TmpFileUploadHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
214
|
+
name: string;
|
|
215
|
+
/**
|
|
216
|
+
* Should parse the original request body instead of batched sub-requests.
|
|
217
|
+
*/
|
|
218
|
+
after: string[];
|
|
219
|
+
/**
|
|
220
|
+
* Should run inside the limit and compression plugins, so spooling receives
|
|
221
|
+
* the size-checked, decompressed bytes.
|
|
222
|
+
*/
|
|
223
|
+
before: string[];
|
|
224
|
+
private readonly tmpDir;
|
|
225
|
+
private readonly maxBodySize;
|
|
226
|
+
constructor(options?: TmpFileUploadHandlerPluginOptions);
|
|
227
|
+
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
228
|
+
private resolveBody;
|
|
229
|
+
/**
|
|
230
|
+
* Enforces a size limit on a body the standard parser handles, counting the
|
|
231
|
+
* raw bytes before handing them back for regular parsing.
|
|
232
|
+
*/
|
|
233
|
+
private parseLimitedBody;
|
|
234
|
+
private spoolFileBody;
|
|
235
|
+
private parseMultipartBody;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export { StaticFileHandlerPlugin, TmpFile, TmpFileUploadHandlerPlugin };
|
|
239
|
+
export type { StaticFileHandlerPluginOptions, TmpFileUploadHandlerPluginMaxBodySize, TmpFileUploadHandlerPluginOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context } from '@orpc/server';
|
|
2
2
|
import { StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
|
|
3
|
+
import { FilePropertyBag } from 'node:buffer';
|
|
3
4
|
|
|
4
5
|
interface StaticFileHandlerPluginOptions {
|
|
5
6
|
/**
|
|
@@ -126,5 +127,113 @@ declare class StaticFileHandlerPlugin<T extends Context> implements StandardHand
|
|
|
126
127
|
private serve;
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
interface TmpFileUploadHandlerPluginMaxBodySize {
|
|
131
|
+
/**
|
|
132
|
+
* The maximum total size in bytes of request body content that is parsed
|
|
133
|
+
* into memory: JSON, URL-encoded forms, and the plain fields of a multipart
|
|
134
|
+
* body. A larger body rejects the request with `PAYLOAD_TOO_LARGE`. Usually
|
|
135
|
+
* the lowest of the three limits, because this content cannot stream anywhere.
|
|
136
|
+
*/
|
|
137
|
+
memory: number;
|
|
138
|
+
/**
|
|
139
|
+
* The maximum total size in bytes of upload content a request streams into
|
|
140
|
+
* temporary files: file bodies and the file parts of a multipart body
|
|
141
|
+
* combined. A larger body rejects the request with `PAYLOAD_TOO_LARGE`.
|
|
142
|
+
*/
|
|
143
|
+
file: number;
|
|
144
|
+
/**
|
|
145
|
+
* The maximum total size in bytes of a request body that is consumed as a
|
|
146
|
+
* stream: event streams and raw binary streams. Enforced while the stream is
|
|
147
|
+
* consumed, so an oversized stream fails at the reader. Usually the highest
|
|
148
|
+
* of the three limits, because this content is consumed on the fly.
|
|
149
|
+
*/
|
|
150
|
+
stream: number;
|
|
151
|
+
}
|
|
152
|
+
interface TmpFileUploadHandlerPluginOptions {
|
|
153
|
+
/**
|
|
154
|
+
* The directory temporary files are created under. Each request that spools
|
|
155
|
+
* an upload gets its own subdirectory inside it, removed when the request
|
|
156
|
+
* finishes.
|
|
157
|
+
*
|
|
158
|
+
* @default os.tmpdir()
|
|
159
|
+
*/
|
|
160
|
+
tmpDir?: string;
|
|
161
|
+
/**
|
|
162
|
+
* The size limit for each kind of request body. Every kind is required when
|
|
163
|
+
* the option is given, so none is left unbounded by accident; set a kind to
|
|
164
|
+
* `Number.POSITIVE_INFINITY` to deliberately leave it unlimited.
|
|
165
|
+
*
|
|
166
|
+
* @default unlimited for every kind
|
|
167
|
+
*/
|
|
168
|
+
maxBodySize?: TmpFileUploadHandlerPluginMaxBodySize;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* A `File` whose content lives in a temporary file on disk and is read lazily,
|
|
172
|
+
* so it can represent an upload far larger than available memory.
|
|
173
|
+
*
|
|
174
|
+
* @see {@link https://orpc.dev/docs/plugins/tmp-file-upload | Tmp File Upload Plugin}
|
|
175
|
+
*/
|
|
176
|
+
declare class TmpFile extends File {
|
|
177
|
+
/**
|
|
178
|
+
* Absolute path of the temporary file holding this file's content.
|
|
179
|
+
* The file is removed when the request finishes, so move or copy it
|
|
180
|
+
* to keep the content. The `File` reads from this path, so it must
|
|
181
|
+
* not be read after the file is moved or removed.
|
|
182
|
+
*/
|
|
183
|
+
readonly path: string;
|
|
184
|
+
constructor(blob: Blob,
|
|
185
|
+
/**
|
|
186
|
+
* Absolute path of the temporary file holding this file's content.
|
|
187
|
+
* The file is removed when the request finishes, so move or copy it
|
|
188
|
+
* to keep the content. The `File` reads from this path, so it must
|
|
189
|
+
* not be read after the file is moved or removed.
|
|
190
|
+
*/
|
|
191
|
+
path: string, name: string, options?: FilePropertyBag);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Parses file uploads into temporary files instead of memory. Bodies the standard
|
|
195
|
+
* body parser would buffer into an in-memory `File`, and multipart file parts, are
|
|
196
|
+
* streamed to disk and surfaced as lazily read {@link TmpFile} instances, so requests
|
|
197
|
+
* far larger than available memory parse in constant memory. Every other body is left
|
|
198
|
+
* to the standard parser.
|
|
199
|
+
*
|
|
200
|
+
* Request body sizes are limited per content category: memory-parsed, spooled to
|
|
201
|
+
* disk, and streamed. This subsumes the request limit plugin while sizing each
|
|
202
|
+
* kind of body to what it actually costs.
|
|
203
|
+
*
|
|
204
|
+
* @remarks
|
|
205
|
+
* Temporary files are removed when the request finishes. A streaming response body,
|
|
206
|
+
* an event iterator or a raw stream, keeps them alive until it completes, so
|
|
207
|
+
* responses that read the upload while streaming work. Any other response is
|
|
208
|
+
* transmitted after removal, so one that embeds the upload itself, as a `File` or
|
|
209
|
+
* inside `FormData`, needs the content copied or the file moved first.
|
|
210
|
+
*
|
|
211
|
+
* @see {@link https://orpc.dev/docs/plugins/tmp-file-upload | Tmp File Upload Plugin}
|
|
212
|
+
*/
|
|
213
|
+
declare class TmpFileUploadHandlerPlugin<T extends Context> implements StandardHandlerPlugin<T> {
|
|
214
|
+
name: string;
|
|
215
|
+
/**
|
|
216
|
+
* Should parse the original request body instead of batched sub-requests.
|
|
217
|
+
*/
|
|
218
|
+
after: string[];
|
|
219
|
+
/**
|
|
220
|
+
* Should run inside the limit and compression plugins, so spooling receives
|
|
221
|
+
* the size-checked, decompressed bytes.
|
|
222
|
+
*/
|
|
223
|
+
before: string[];
|
|
224
|
+
private readonly tmpDir;
|
|
225
|
+
private readonly maxBodySize;
|
|
226
|
+
constructor(options?: TmpFileUploadHandlerPluginOptions);
|
|
227
|
+
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
228
|
+
private resolveBody;
|
|
229
|
+
/**
|
|
230
|
+
* Enforces a size limit on a body the standard parser handles, counting the
|
|
231
|
+
* raw bytes before handing them back for regular parsing.
|
|
232
|
+
*/
|
|
233
|
+
private parseLimitedBody;
|
|
234
|
+
private spoolFileBody;
|
|
235
|
+
private parseMultipartBody;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export { StaticFileHandlerPlugin, TmpFile, TmpFileUploadHandlerPlugin };
|
|
239
|
+
export type { StaticFileHandlerPluginOptions, TmpFileUploadHandlerPluginMaxBodySize, TmpFileUploadHandlerPluginOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { createReadStream } from 'node:fs';
|
|
2
|
-
import { realpath, stat } from 'node:fs/promises';
|
|
1
|
+
import { createReadStream, openAsBlob } from 'node:fs';
|
|
2
|
+
import { realpath, stat, mkdtemp, appendFile, rm } from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { Readable } from 'node:stream';
|
|
5
|
-
import { toArray, mergeHttpPath, tryDecodeURIComponent, matchesHttpPathPrefix, isCompressibleContentType, parseAcceptEncodingQualities, getOpenTelemetryConfig } from '@orpc/shared';
|
|
6
|
-
import { parseStandardUrl, flattenStandardHeader } from '@standardserver/core';
|
|
5
|
+
import { toArray, mergeHttpPath, tryDecodeURIComponent, matchesHttpPathPrefix, isCompressibleContentType, parseAcceptEncodingQualities, getOpenTelemetryConfig, isAsyncIteratorObject, override, wrapAsyncIterator, wrapReadableStream } from '@orpc/shared';
|
|
6
|
+
import { parseStandardUrl, flattenStandardHeader, resolveStandardBodyHint, getFilenameFromContentDisposition } from '@standardserver/core';
|
|
7
7
|
import mime from 'mime';
|
|
8
|
+
import { Buffer } from 'node:buffer';
|
|
9
|
+
import { tmpdir } from 'node:os';
|
|
10
|
+
import { ORPCError } from '@orpc/server';
|
|
11
|
+
import { toFetchHeaders, toStandardBody } from '@standardserver/fetch';
|
|
8
12
|
|
|
9
13
|
const TEXT_CONTENT_TYPE_REGEX = /^text\//;
|
|
10
14
|
const PRECOMPRESSED_ENCODINGS = [
|
|
@@ -325,4 +329,407 @@ function parseByteRange(range, size) {
|
|
|
325
329
|
return [start, end];
|
|
326
330
|
}
|
|
327
331
|
|
|
328
|
-
|
|
332
|
+
const MAX_PART_HEADER_SIZE = 16 * 1024;
|
|
333
|
+
const CRLF = Buffer.from("\r\n");
|
|
334
|
+
const HEADER_BLOCK_END = Buffer.from("\r\n\r\n");
|
|
335
|
+
async function parseMultipart(source, boundary, onPart) {
|
|
336
|
+
const delimiter = Buffer.from(`\r
|
|
337
|
+
--${boundary}`);
|
|
338
|
+
let buffer = CRLF;
|
|
339
|
+
let state = "preamble";
|
|
340
|
+
let writer;
|
|
341
|
+
let done = false;
|
|
342
|
+
const process = async () => {
|
|
343
|
+
while (true) {
|
|
344
|
+
if (state === "preamble" || state === "body") {
|
|
345
|
+
const index = buffer.indexOf(delimiter);
|
|
346
|
+
if (index === -1) {
|
|
347
|
+
const settledLength = buffer.length - delimiter.length + 1;
|
|
348
|
+
if (settledLength > 0) {
|
|
349
|
+
if (state === "body") {
|
|
350
|
+
await writer.write(buffer.subarray(0, settledLength));
|
|
351
|
+
}
|
|
352
|
+
buffer = buffer.subarray(settledLength);
|
|
353
|
+
}
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (state === "body") {
|
|
357
|
+
if (index > 0) {
|
|
358
|
+
await writer.write(buffer.subarray(0, index));
|
|
359
|
+
}
|
|
360
|
+
await writer.end();
|
|
361
|
+
writer = void 0;
|
|
362
|
+
}
|
|
363
|
+
buffer = buffer.subarray(index + delimiter.length);
|
|
364
|
+
state = "delimiter-end";
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
if (state === "delimiter-end") {
|
|
368
|
+
if (buffer.length < 2) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
if (buffer[0] === 45 && buffer[1] === 45) {
|
|
372
|
+
done = true;
|
|
373
|
+
buffer = Buffer.alloc(0);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
let index = 0;
|
|
377
|
+
while (index < buffer.length && (buffer[index] === 32 || buffer[index] === 9)) {
|
|
378
|
+
index++;
|
|
379
|
+
}
|
|
380
|
+
if (index + 1 >= buffer.length) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (buffer[index] !== 13 || buffer[index + 1] !== 10) {
|
|
384
|
+
throw new TypeError("Invalid multipart body: expected CRLF after a boundary delimiter");
|
|
385
|
+
}
|
|
386
|
+
buffer = buffer.subarray(index + 2);
|
|
387
|
+
state = "headers";
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
if (buffer[0] === 13 && buffer[1] === 10) {
|
|
391
|
+
throw new TypeError("Invalid multipart body: part is missing the content-disposition header");
|
|
392
|
+
}
|
|
393
|
+
const headerEnd = buffer.indexOf(HEADER_BLOCK_END);
|
|
394
|
+
if (headerEnd === -1) {
|
|
395
|
+
if (buffer.length > MAX_PART_HEADER_SIZE) {
|
|
396
|
+
throw new TypeError("Invalid multipart body: part headers exceed the maximum allowed size");
|
|
397
|
+
}
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
const part = parsePartHeaders(buffer.subarray(0, headerEnd).toString());
|
|
401
|
+
buffer = buffer.subarray(headerEnd + HEADER_BLOCK_END.length);
|
|
402
|
+
writer = await onPart(part);
|
|
403
|
+
state = "body";
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
for await (const chunk of source) {
|
|
407
|
+
if (done) {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
buffer = buffer.length === 0 ? Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) : Buffer.concat([buffer, chunk]);
|
|
411
|
+
await process();
|
|
412
|
+
}
|
|
413
|
+
if (!done) {
|
|
414
|
+
throw new TypeError("Invalid multipart body: unexpected end of body");
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
function parsePartHeaders(block) {
|
|
418
|
+
let contentDisposition;
|
|
419
|
+
let contentType;
|
|
420
|
+
for (const line of block.split("\r\n")) {
|
|
421
|
+
const colon = line.indexOf(":");
|
|
422
|
+
if (colon === -1) {
|
|
423
|
+
throw new TypeError("Invalid multipart body: malformed part header");
|
|
424
|
+
}
|
|
425
|
+
const name2 = line.slice(0, colon).trim().toLowerCase();
|
|
426
|
+
if (name2 === "content-disposition") {
|
|
427
|
+
contentDisposition = line.slice(colon + 1).trim();
|
|
428
|
+
} else if (name2 === "content-type") {
|
|
429
|
+
contentType = line.slice(colon + 1).trim();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
if (contentDisposition === void 0) {
|
|
433
|
+
throw new TypeError("Invalid multipart body: part is missing the content-disposition header");
|
|
434
|
+
}
|
|
435
|
+
const semicolon = contentDisposition.indexOf(";");
|
|
436
|
+
const dispositionType = (semicolon === -1 ? contentDisposition : contentDisposition.slice(0, semicolon)).trim().toLowerCase();
|
|
437
|
+
if (dispositionType !== "form-data") {
|
|
438
|
+
throw new TypeError("Invalid multipart body: content-disposition must be form-data");
|
|
439
|
+
}
|
|
440
|
+
const parameters = parseHeaderParameters(contentDisposition);
|
|
441
|
+
const name = parameters.get("name");
|
|
442
|
+
if (name === void 0) {
|
|
443
|
+
throw new TypeError("Invalid multipart body: content-disposition header is missing the name parameter");
|
|
444
|
+
}
|
|
445
|
+
const filename = parameters.get("filename");
|
|
446
|
+
return {
|
|
447
|
+
name: decodeContentDispositionParameter(name),
|
|
448
|
+
filename: filename === void 0 ? void 0 : decodeContentDispositionParameter(filename),
|
|
449
|
+
type: contentType
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
function decodeContentDispositionParameter(value) {
|
|
453
|
+
return value.replaceAll("%22", '"').replaceAll("%0D", "\r").replaceAll("%0A", "\n");
|
|
454
|
+
}
|
|
455
|
+
function parseHeaderParameters(header) {
|
|
456
|
+
const parameters = /* @__PURE__ */ new Map();
|
|
457
|
+
let index = header.indexOf(";");
|
|
458
|
+
while (index !== -1 && index < header.length) {
|
|
459
|
+
index++;
|
|
460
|
+
while (index < header.length && (header[index] === " " || header[index] === " ")) {
|
|
461
|
+
index++;
|
|
462
|
+
}
|
|
463
|
+
const equals = header.indexOf("=", index);
|
|
464
|
+
const nextSemicolon = header.indexOf(";", index);
|
|
465
|
+
if (equals === -1 || nextSemicolon !== -1 && nextSemicolon < equals) {
|
|
466
|
+
if (nextSemicolon === -1) {
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
index = nextSemicolon;
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
const key = header.slice(index, equals).trim().toLowerCase();
|
|
473
|
+
index = equals + 1;
|
|
474
|
+
let value;
|
|
475
|
+
if (header[index] === '"') {
|
|
476
|
+
const closing = header.indexOf('"', index + 1);
|
|
477
|
+
value = closing === -1 ? header.slice(index + 1) : header.slice(index + 1, closing);
|
|
478
|
+
index = closing === -1 ? -1 : header.indexOf(";", closing + 1);
|
|
479
|
+
} else {
|
|
480
|
+
const semicolon = header.indexOf(";", index);
|
|
481
|
+
value = (semicolon === -1 ? header.slice(index) : header.slice(index, semicolon)).trim();
|
|
482
|
+
index = semicolon;
|
|
483
|
+
}
|
|
484
|
+
if (!parameters.has(key)) {
|
|
485
|
+
parameters.set(key, value);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return parameters;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
class TmpFile extends File {
|
|
492
|
+
constructor(blob, path2, name, options) {
|
|
493
|
+
super([blob], name, options);
|
|
494
|
+
this.path = path2;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
class TmpFileUploadHandlerPlugin {
|
|
498
|
+
name = "~tmp-file-upload";
|
|
499
|
+
/**
|
|
500
|
+
* Should parse the original request body instead of batched sub-requests.
|
|
501
|
+
*/
|
|
502
|
+
after = ["~batch"];
|
|
503
|
+
/**
|
|
504
|
+
* Should run inside the limit and compression plugins, so spooling receives
|
|
505
|
+
* the size-checked, decompressed bytes.
|
|
506
|
+
*/
|
|
507
|
+
before = ["~request-limit", "~request-compression"];
|
|
508
|
+
tmpDir;
|
|
509
|
+
maxBodySize;
|
|
510
|
+
constructor(options = {}) {
|
|
511
|
+
this.tmpDir = options.tmpDir ?? tmpdir();
|
|
512
|
+
this.maxBodySize = options.maxBodySize ?? {
|
|
513
|
+
memory: Number.POSITIVE_INFINITY,
|
|
514
|
+
file: Number.POSITIVE_INFINITY,
|
|
515
|
+
stream: Number.POSITIVE_INFINITY
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
init(options) {
|
|
519
|
+
const routingInterceptor = async ({ next, ...interceptorOptions }) => {
|
|
520
|
+
const tmpFiles = new RequestTmpFiles(this.tmpDir);
|
|
521
|
+
let cleanupDeferred = false;
|
|
522
|
+
try {
|
|
523
|
+
const result = await next({
|
|
524
|
+
...interceptorOptions,
|
|
525
|
+
request: {
|
|
526
|
+
...interceptorOptions.request,
|
|
527
|
+
resolveBody: (hint) => this.resolveBody(interceptorOptions.request, hint, tmpFiles)
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
if (result.matched && tmpFiles.inUse) {
|
|
531
|
+
const body = result.response.body;
|
|
532
|
+
if (isAsyncIteratorObject(body)) {
|
|
533
|
+
cleanupDeferred = true;
|
|
534
|
+
return {
|
|
535
|
+
matched: true,
|
|
536
|
+
response: {
|
|
537
|
+
...result.response,
|
|
538
|
+
/**
|
|
539
|
+
* @warning
|
|
540
|
+
* Remember use `override` for AsyncIteratorObject to remain other special properties
|
|
541
|
+
*/
|
|
542
|
+
body: override(body, wrapAsyncIterator(body, { onFinish: () => tmpFiles.cleanup() }))
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
if (body instanceof ReadableStream) {
|
|
547
|
+
cleanupDeferred = true;
|
|
548
|
+
return {
|
|
549
|
+
matched: true,
|
|
550
|
+
response: {
|
|
551
|
+
...result.response,
|
|
552
|
+
body: wrapReadableStream(body, { onFinish: () => tmpFiles.cleanup() })
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return result;
|
|
558
|
+
} finally {
|
|
559
|
+
if (!cleanupDeferred) {
|
|
560
|
+
await tmpFiles.cleanup();
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
return {
|
|
565
|
+
...options,
|
|
566
|
+
routingInterceptors: [routingInterceptor, ...toArray(options.routingInterceptors)]
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
async resolveBody(request, hint, tmpFiles) {
|
|
570
|
+
const resolvedHint = hint ?? resolveStandardBodyHint(request.headers);
|
|
571
|
+
if (resolvedHint === "form-data") {
|
|
572
|
+
return this.parseMultipartBody(request, tmpFiles);
|
|
573
|
+
}
|
|
574
|
+
if (resolvedHint === "file") {
|
|
575
|
+
return this.spoolFileBody(request, tmpFiles);
|
|
576
|
+
}
|
|
577
|
+
if (resolvedHint === "json" || resolvedHint === "url-search-params") {
|
|
578
|
+
return this.parseLimitedBody(request, hint, resolvedHint, this.maxBodySize.memory);
|
|
579
|
+
}
|
|
580
|
+
if (resolvedHint === "event-stream" || resolvedHint === "octet-stream") {
|
|
581
|
+
return this.parseLimitedBody(request, hint, resolvedHint, this.maxBodySize.stream);
|
|
582
|
+
}
|
|
583
|
+
return request.resolveBody(hint);
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Enforces a size limit on a body the standard parser handles, counting the
|
|
587
|
+
* raw bytes before handing them back for regular parsing.
|
|
588
|
+
*/
|
|
589
|
+
async parseLimitedBody(request, hint, resolvedHint, limit) {
|
|
590
|
+
if (limit === Number.POSITIVE_INFINITY) {
|
|
591
|
+
return request.resolveBody(hint);
|
|
592
|
+
}
|
|
593
|
+
assertContentLengthWithin(request.headers, limit);
|
|
594
|
+
const stream = await request.resolveBody("octet-stream");
|
|
595
|
+
if (!(stream instanceof ReadableStream)) {
|
|
596
|
+
return stream;
|
|
597
|
+
}
|
|
598
|
+
const response = new Response(limitStream(stream, limit), {
|
|
599
|
+
headers: toFetchHeaders(request.headers)
|
|
600
|
+
});
|
|
601
|
+
return toStandardBody(response, { hint: resolvedHint });
|
|
602
|
+
}
|
|
603
|
+
async spoolFileBody(request, tmpFiles) {
|
|
604
|
+
assertContentLengthWithin(request.headers, this.maxBodySize.file);
|
|
605
|
+
const stream = await request.resolveBody("octet-stream");
|
|
606
|
+
if (!(stream instanceof ReadableStream)) {
|
|
607
|
+
return stream;
|
|
608
|
+
}
|
|
609
|
+
const contentDisposition = flattenStandardHeader(request.headers["content-disposition"]);
|
|
610
|
+
const fileName = contentDisposition !== void 0 ? getFilenameFromContentDisposition(contentDisposition) : void 0;
|
|
611
|
+
const contentType = flattenStandardHeader(request.headers["content-type"]);
|
|
612
|
+
const limited = this.maxBodySize.file === Number.POSITIVE_INFINITY ? stream : limitStream(stream, this.maxBodySize.file);
|
|
613
|
+
const tmpPath = await tmpFiles.allocate();
|
|
614
|
+
for await (const chunk of limited) {
|
|
615
|
+
await tmpFiles.append(tmpPath, chunk);
|
|
616
|
+
}
|
|
617
|
+
return tmpFiles.seal(tmpPath, fileName ?? "blob", contentType ?? "");
|
|
618
|
+
}
|
|
619
|
+
async parseMultipartBody(request, tmpFiles) {
|
|
620
|
+
const contentType = flattenStandardHeader(request.headers["content-type"]);
|
|
621
|
+
const boundary = contentType === void 0 ? void 0 : parseHeaderParameters(contentType).get("boundary");
|
|
622
|
+
if (boundary === void 0 || boundary === "") {
|
|
623
|
+
throw new TypeError("Invalid multipart body: content-type header is missing the boundary parameter");
|
|
624
|
+
}
|
|
625
|
+
const totalLimit = this.maxBodySize.memory + this.maxBodySize.file;
|
|
626
|
+
assertContentLengthWithin(request.headers, totalLimit);
|
|
627
|
+
const stream = await request.resolveBody("octet-stream");
|
|
628
|
+
if (!(stream instanceof ReadableStream)) {
|
|
629
|
+
return stream;
|
|
630
|
+
}
|
|
631
|
+
const limited = totalLimit === Number.POSITIVE_INFINITY ? stream : limitStream(stream, totalLimit);
|
|
632
|
+
const form = new FormData();
|
|
633
|
+
let memoryUsed = 0;
|
|
634
|
+
let fileUsed = 0;
|
|
635
|
+
await parseMultipart(limited, boundary, (part) => {
|
|
636
|
+
const name = part.name;
|
|
637
|
+
if (part.filename === void 0) {
|
|
638
|
+
const chunks = [];
|
|
639
|
+
return {
|
|
640
|
+
write: (chunk) => {
|
|
641
|
+
memoryUsed += chunk.length;
|
|
642
|
+
if (memoryUsed > this.maxBodySize.memory) {
|
|
643
|
+
throw new ORPCError("PAYLOAD_TOO_LARGE");
|
|
644
|
+
}
|
|
645
|
+
chunks.push(Buffer.from(chunk));
|
|
646
|
+
},
|
|
647
|
+
end: () => {
|
|
648
|
+
form.append(name, Buffer.concat(chunks).toString());
|
|
649
|
+
}
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
const filename = part.filename;
|
|
653
|
+
const type = part.type ?? "text/plain";
|
|
654
|
+
let tmpPath;
|
|
655
|
+
return {
|
|
656
|
+
write: async (chunk) => {
|
|
657
|
+
fileUsed += chunk.length;
|
|
658
|
+
if (fileUsed > this.maxBodySize.file) {
|
|
659
|
+
throw new ORPCError("PAYLOAD_TOO_LARGE");
|
|
660
|
+
}
|
|
661
|
+
tmpPath ??= await tmpFiles.allocate();
|
|
662
|
+
await tmpFiles.append(tmpPath, chunk);
|
|
663
|
+
},
|
|
664
|
+
end: async () => {
|
|
665
|
+
tmpPath ??= await tmpFiles.allocate();
|
|
666
|
+
form.append(name, await tmpFiles.seal(tmpPath, filename, type));
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
});
|
|
670
|
+
return form;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
function assertContentLengthWithin(headers, limit) {
|
|
674
|
+
const contentLength = Number(flattenStandardHeader(headers["content-length"]));
|
|
675
|
+
if (Number.isFinite(contentLength) && contentLength > limit) {
|
|
676
|
+
throw new ORPCError("PAYLOAD_TOO_LARGE");
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
function limitStream(stream, limit) {
|
|
680
|
+
let total = 0;
|
|
681
|
+
return stream.pipeThrough(new TransformStream({
|
|
682
|
+
transform(chunk, controller) {
|
|
683
|
+
total += chunk.byteLength;
|
|
684
|
+
if (total > limit) {
|
|
685
|
+
controller.error(new ORPCError("PAYLOAD_TOO_LARGE"));
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
controller.enqueue(chunk);
|
|
689
|
+
}
|
|
690
|
+
}));
|
|
691
|
+
}
|
|
692
|
+
const EMPTY_CHUNK = new Uint8Array(0);
|
|
693
|
+
class RequestTmpFiles {
|
|
694
|
+
constructor(tmpDir) {
|
|
695
|
+
this.tmpDir = tmpDir;
|
|
696
|
+
}
|
|
697
|
+
dir;
|
|
698
|
+
count = 0;
|
|
699
|
+
get inUse() {
|
|
700
|
+
return this.dir !== void 0;
|
|
701
|
+
}
|
|
702
|
+
async allocate() {
|
|
703
|
+
try {
|
|
704
|
+
this.dir ??= mkdtemp(path.join(this.tmpDir, "orpc-upload-"));
|
|
705
|
+
return path.join(await this.dir, String(this.count++));
|
|
706
|
+
} catch (cause) {
|
|
707
|
+
throw new ORPCError("INTERNAL_SERVER_ERROR", { cause });
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
async append(tmpPath, chunk) {
|
|
711
|
+
try {
|
|
712
|
+
await appendFile(tmpPath, chunk);
|
|
713
|
+
} catch (cause) {
|
|
714
|
+
throw new ORPCError("INTERNAL_SERVER_ERROR", { cause });
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
async seal(tmpPath, name, type) {
|
|
718
|
+
try {
|
|
719
|
+
await appendFile(tmpPath, EMPTY_CHUNK);
|
|
720
|
+
return new TmpFile(await openAsBlob(tmpPath), tmpPath, name, { type });
|
|
721
|
+
} catch (cause) {
|
|
722
|
+
throw new ORPCError("INTERNAL_SERVER_ERROR", { cause });
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
async cleanup() {
|
|
726
|
+
if (this.dir !== void 0) {
|
|
727
|
+
try {
|
|
728
|
+
await rm(await this.dir, { recursive: true, force: true });
|
|
729
|
+
} catch {
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
export { StaticFileHandlerPlugin, TmpFile, TmpFileUploadHandlerPlugin };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orpc/node",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.28",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"funding": "https://github.com/sponsors/dinwwwh",
|
|
7
7
|
"homepage": "https://orpc.dev",
|
|
@@ -27,13 +27,15 @@
|
|
|
27
27
|
"dist"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@standardserver/core": "^0.
|
|
30
|
+
"@standardserver/core": "^0.8.0",
|
|
31
|
+
"@standardserver/fetch": "^0.8.0",
|
|
31
32
|
"mime": "^4.1.0",
|
|
32
|
-
"@orpc/
|
|
33
|
-
"@orpc/
|
|
33
|
+
"@orpc/server": "2.0.0-beta.28",
|
|
34
|
+
"@orpc/shared": "2.0.0-beta.28"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
|
-
"supertest": "^7.2.2"
|
|
37
|
+
"supertest": "^7.2.2",
|
|
38
|
+
"@orpc/client": "2.0.0-beta.28"
|
|
37
39
|
},
|
|
38
40
|
"scripts": {
|
|
39
41
|
"build": "unbuild",
|