@positronic/cli 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/dist/src/cli.js +739 -0
  2. package/dist/src/commands/backend.js +199 -0
  3. package/dist/src/commands/brain.js +446 -0
  4. package/dist/src/commands/brain.test.js +2936 -0
  5. package/dist/src/commands/helpers.js +1315 -0
  6. package/dist/src/commands/helpers.test.js +832 -0
  7. package/dist/src/commands/project-config-manager.js +197 -0
  8. package/dist/src/commands/project.js +130 -0
  9. package/dist/src/commands/project.test.js +1201 -0
  10. package/dist/src/commands/resources.js +272 -0
  11. package/dist/src/commands/resources.test.js +2511 -0
  12. package/dist/src/commands/schedule.js +73 -0
  13. package/dist/src/commands/schedule.test.js +1235 -0
  14. package/dist/src/commands/secret.js +87 -0
  15. package/dist/src/commands/secret.test.d.js +1 -0
  16. package/dist/src/commands/secret.test.js +761 -0
  17. package/dist/src/commands/server.js +816 -0
  18. package/dist/src/commands/server.test.js +1237 -0
  19. package/dist/src/commands/test-utils.js +737 -0
  20. package/dist/src/components/brain-history.js +169 -0
  21. package/dist/src/components/brain-list.js +108 -0
  22. package/dist/src/components/brain-rerun.js +313 -0
  23. package/dist/src/components/brain-show.js +65 -0
  24. package/dist/src/components/error.js +19 -0
  25. package/dist/src/components/project-add.js +95 -0
  26. package/dist/src/components/project-create.js +276 -0
  27. package/dist/src/components/project-list.js +88 -0
  28. package/dist/src/components/project-remove.js +91 -0
  29. package/dist/src/components/project-select.js +224 -0
  30. package/dist/src/components/project-show.js +41 -0
  31. package/dist/src/components/resource-clear.js +152 -0
  32. package/dist/src/components/resource-delete.js +189 -0
  33. package/dist/src/components/resource-list.js +174 -0
  34. package/dist/src/components/resource-sync.js +386 -0
  35. package/dist/src/components/resource-types.js +243 -0
  36. package/dist/src/components/resource-upload.js +366 -0
  37. package/dist/src/components/schedule-create.js +259 -0
  38. package/dist/src/components/schedule-delete.js +161 -0
  39. package/dist/src/components/schedule-list.js +176 -0
  40. package/dist/src/components/schedule-runs.js +103 -0
  41. package/dist/src/components/secret-bulk.js +262 -0
  42. package/dist/src/components/secret-create.js +199 -0
  43. package/dist/src/components/secret-delete.js +190 -0
  44. package/dist/src/components/secret-list.js +190 -0
  45. package/dist/src/components/secret-sync.js +303 -0
  46. package/dist/src/components/watch.js +184 -0
  47. package/dist/src/hooks/useApi.js +512 -0
  48. package/dist/src/positronic.js +33 -0
  49. package/dist/src/test/mock-api-client.js +371 -0
  50. package/dist/src/test/test-dev-server.js +1376 -0
  51. package/dist/types/cli.d.ts +9 -0
  52. package/dist/types/cli.d.ts.map +1 -0
  53. package/dist/types/commands/backend.d.ts +6 -0
  54. package/dist/types/commands/backend.d.ts.map +1 -0
  55. package/dist/types/commands/brain.d.ts +35 -0
  56. package/dist/types/commands/brain.d.ts.map +1 -0
  57. package/dist/types/commands/helpers.d.ts +55 -0
  58. package/dist/types/commands/helpers.d.ts.map +1 -0
  59. package/dist/types/commands/project-config-manager.d.ts +37 -0
  60. package/dist/types/commands/project-config-manager.d.ts.map +1 -0
  61. package/dist/types/commands/project.d.ts +55 -0
  62. package/dist/types/commands/project.d.ts.map +1 -0
  63. package/dist/types/commands/resources.d.ts +13 -0
  64. package/dist/types/commands/resources.d.ts.map +1 -0
  65. package/dist/types/commands/schedule.d.ts +27 -0
  66. package/dist/types/commands/schedule.d.ts.map +1 -0
  67. package/dist/types/commands/secret.d.ts +23 -0
  68. package/dist/types/commands/secret.d.ts.map +1 -0
  69. package/dist/types/commands/server.d.ts +12 -0
  70. package/dist/types/commands/server.d.ts.map +1 -0
  71. package/dist/types/commands/test-utils.d.ts +45 -0
  72. package/dist/types/commands/test-utils.d.ts.map +1 -0
  73. package/dist/types/components/brain-history.d.ts +7 -0
  74. package/dist/types/components/brain-history.d.ts.map +1 -0
  75. package/dist/types/components/brain-list.d.ts +2 -0
  76. package/dist/types/components/brain-list.d.ts.map +1 -0
  77. package/dist/types/components/brain-rerun.d.ts +9 -0
  78. package/dist/types/components/brain-rerun.d.ts.map +1 -0
  79. package/dist/types/components/brain-show.d.ts +6 -0
  80. package/dist/types/components/brain-show.d.ts.map +1 -0
  81. package/dist/types/components/error.d.ts +10 -0
  82. package/dist/types/components/error.d.ts.map +1 -0
  83. package/dist/types/components/project-add.d.ts +9 -0
  84. package/dist/types/components/project-add.d.ts.map +1 -0
  85. package/dist/types/components/project-create.d.ts +6 -0
  86. package/dist/types/components/project-create.d.ts.map +1 -0
  87. package/dist/types/components/project-list.d.ts +7 -0
  88. package/dist/types/components/project-list.d.ts.map +1 -0
  89. package/dist/types/components/project-remove.d.ts +8 -0
  90. package/dist/types/components/project-remove.d.ts.map +1 -0
  91. package/dist/types/components/project-select.d.ts +8 -0
  92. package/dist/types/components/project-select.d.ts.map +1 -0
  93. package/dist/types/components/project-show.d.ts +7 -0
  94. package/dist/types/components/project-show.d.ts.map +1 -0
  95. package/dist/types/components/resource-clear.d.ts +2 -0
  96. package/dist/types/components/resource-clear.d.ts.map +1 -0
  97. package/dist/types/components/resource-delete.d.ts +9 -0
  98. package/dist/types/components/resource-delete.d.ts.map +1 -0
  99. package/dist/types/components/resource-list.d.ts +2 -0
  100. package/dist/types/components/resource-list.d.ts.map +1 -0
  101. package/dist/types/components/resource-sync.d.ts +8 -0
  102. package/dist/types/components/resource-sync.d.ts.map +1 -0
  103. package/dist/types/components/resource-types.d.ts +7 -0
  104. package/dist/types/components/resource-types.d.ts.map +1 -0
  105. package/dist/types/components/resource-upload.d.ts +8 -0
  106. package/dist/types/components/resource-upload.d.ts.map +1 -0
  107. package/dist/types/components/schedule-create.d.ts +7 -0
  108. package/dist/types/components/schedule-create.d.ts.map +1 -0
  109. package/dist/types/components/schedule-delete.d.ts +7 -0
  110. package/dist/types/components/schedule-delete.d.ts.map +1 -0
  111. package/dist/types/components/schedule-list.d.ts +6 -0
  112. package/dist/types/components/schedule-list.d.ts.map +1 -0
  113. package/dist/types/components/schedule-runs.d.ts +8 -0
  114. package/dist/types/components/schedule-runs.d.ts.map +1 -0
  115. package/dist/types/components/secret-bulk.d.ts +8 -0
  116. package/dist/types/components/secret-bulk.d.ts.map +1 -0
  117. package/dist/types/components/secret-create.d.ts +9 -0
  118. package/dist/types/components/secret-create.d.ts.map +1 -0
  119. package/dist/types/components/secret-delete.d.ts +8 -0
  120. package/dist/types/components/secret-delete.d.ts.map +1 -0
  121. package/dist/types/components/secret-list.d.ts +7 -0
  122. package/dist/types/components/secret-list.d.ts.map +1 -0
  123. package/dist/types/components/secret-sync.d.ts +9 -0
  124. package/dist/types/components/secret-sync.d.ts.map +1 -0
  125. package/dist/types/components/watch.d.ts +7 -0
  126. package/dist/types/components/watch.d.ts.map +1 -0
  127. package/dist/types/hooks/useApi.d.ts +29 -0
  128. package/dist/types/hooks/useApi.d.ts.map +1 -0
  129. package/dist/types/positronic.d.ts +3 -0
  130. package/dist/types/positronic.d.ts.map +1 -0
  131. package/dist/types/test/mock-api-client.d.ts +25 -0
  132. package/dist/types/test/mock-api-client.d.ts.map +1 -0
  133. package/dist/types/test/test-dev-server.d.ts +129 -0
  134. package/dist/types/test/test-dev-server.d.ts.map +1 -0
  135. package/package.json +37 -0
  136. package/src/cli.ts +981 -0
  137. package/src/commands/backend.ts +63 -0
  138. package/src/commands/brain.test.ts +1004 -0
  139. package/src/commands/brain.ts +215 -0
  140. package/src/commands/helpers.test.ts +487 -0
  141. package/src/commands/helpers.ts +870 -0
  142. package/src/commands/project-config-manager.ts +152 -0
  143. package/src/commands/project.test.ts +502 -0
  144. package/src/commands/project.ts +109 -0
  145. package/src/commands/resources.test.ts +1052 -0
  146. package/src/commands/resources.ts +97 -0
  147. package/src/commands/schedule.test.ts +481 -0
  148. package/src/commands/schedule.ts +65 -0
  149. package/src/commands/secret.test.ts +210 -0
  150. package/src/commands/secret.ts +50 -0
  151. package/src/commands/server.test.ts +493 -0
  152. package/src/commands/server.ts +353 -0
  153. package/src/commands/test-utils.ts +324 -0
  154. package/src/components/brain-history.tsx +198 -0
  155. package/src/components/brain-list.tsx +105 -0
  156. package/src/components/brain-rerun.tsx +111 -0
  157. package/src/components/brain-show.tsx +92 -0
  158. package/src/components/error.tsx +24 -0
  159. package/src/components/project-add.tsx +59 -0
  160. package/src/components/project-create.tsx +83 -0
  161. package/src/components/project-list.tsx +83 -0
  162. package/src/components/project-remove.tsx +55 -0
  163. package/src/components/project-select.tsx +200 -0
  164. package/src/components/project-show.tsx +58 -0
  165. package/src/components/resource-clear.tsx +127 -0
  166. package/src/components/resource-delete.tsx +160 -0
  167. package/src/components/resource-list.tsx +177 -0
  168. package/src/components/resource-sync.tsx +170 -0
  169. package/src/components/resource-types.tsx +55 -0
  170. package/src/components/resource-upload.tsx +182 -0
  171. package/src/components/schedule-create.tsx +90 -0
  172. package/src/components/schedule-delete.tsx +116 -0
  173. package/src/components/schedule-list.tsx +186 -0
  174. package/src/components/schedule-runs.tsx +151 -0
  175. package/src/components/secret-bulk.tsx +79 -0
  176. package/src/components/secret-create.tsx +49 -0
  177. package/src/components/secret-delete.tsx +41 -0
  178. package/src/components/secret-list.tsx +41 -0
  179. package/src/components/watch.tsx +155 -0
  180. package/src/hooks/useApi.ts +183 -0
  181. package/src/positronic.ts +40 -0
  182. package/src/test/data/resources/config.json +1 -0
  183. package/src/test/data/resources/data/config.json +1 -0
  184. package/src/test/data/resources/data/logo.png +2 -0
  185. package/src/test/data/resources/docs/api.md +3 -0
  186. package/src/test/data/resources/docs/readme.md +3 -0
  187. package/src/test/data/resources/example.md +3 -0
  188. package/src/test/data/resources/file with spaces.txt +1 -0
  189. package/src/test/data/resources/readme.md +3 -0
  190. package/src/test/data/resources/test.txt +1 -0
  191. package/src/test/mock-api-client.ts +145 -0
  192. package/src/test/test-dev-server.ts +1003 -0
  193. package/tsconfig.json +11 -0
@@ -0,0 +1,1315 @@
1
+ function _array_like_to_array(arr, len) {
2
+ if (len == null || len > arr.length) len = arr.length;
3
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
+ return arr2;
5
+ }
6
+ function _array_with_holes(arr) {
7
+ if (Array.isArray(arr)) return arr;
8
+ }
9
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
10
+ try {
11
+ var info = gen[key](arg);
12
+ var value = info.value;
13
+ } catch (error) {
14
+ reject(error);
15
+ return;
16
+ }
17
+ if (info.done) {
18
+ resolve(value);
19
+ } else {
20
+ Promise.resolve(value).then(_next, _throw);
21
+ }
22
+ }
23
+ function _async_to_generator(fn) {
24
+ return function() {
25
+ var self = this, args = arguments;
26
+ return new Promise(function(resolve, reject) {
27
+ var gen = fn.apply(self, args);
28
+ function _next(value) {
29
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
30
+ }
31
+ function _throw(err) {
32
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
33
+ }
34
+ _next(undefined);
35
+ });
36
+ };
37
+ }
38
+ function _define_property(obj, key, value) {
39
+ if (key in obj) {
40
+ Object.defineProperty(obj, key, {
41
+ value: value,
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true
45
+ });
46
+ } else {
47
+ obj[key] = value;
48
+ }
49
+ return obj;
50
+ }
51
+ function _iterable_to_array_limit(arr, i) {
52
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
53
+ if (_i == null) return;
54
+ var _arr = [];
55
+ var _n = true;
56
+ var _d = false;
57
+ var _s, _e;
58
+ try {
59
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
60
+ _arr.push(_s.value);
61
+ if (i && _arr.length === i) break;
62
+ }
63
+ } catch (err) {
64
+ _d = true;
65
+ _e = err;
66
+ } finally{
67
+ try {
68
+ if (!_n && _i["return"] != null) _i["return"]();
69
+ } finally{
70
+ if (_d) throw _e;
71
+ }
72
+ }
73
+ return _arr;
74
+ }
75
+ function _non_iterable_rest() {
76
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
77
+ }
78
+ function _object_spread(target) {
79
+ for(var i = 1; i < arguments.length; i++){
80
+ var source = arguments[i] != null ? arguments[i] : {};
81
+ var ownKeys = Object.keys(source);
82
+ if (typeof Object.getOwnPropertySymbols === "function") {
83
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
84
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
85
+ }));
86
+ }
87
+ ownKeys.forEach(function(key) {
88
+ _define_property(target, key, source[key]);
89
+ });
90
+ }
91
+ return target;
92
+ }
93
+ function ownKeys(object, enumerableOnly) {
94
+ var keys = Object.keys(object);
95
+ if (Object.getOwnPropertySymbols) {
96
+ var symbols = Object.getOwnPropertySymbols(object);
97
+ if (enumerableOnly) {
98
+ symbols = symbols.filter(function(sym) {
99
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
100
+ });
101
+ }
102
+ keys.push.apply(keys, symbols);
103
+ }
104
+ return keys;
105
+ }
106
+ function _object_spread_props(target, source) {
107
+ source = source != null ? source : {};
108
+ if (Object.getOwnPropertyDescriptors) {
109
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
110
+ } else {
111
+ ownKeys(Object(source)).forEach(function(key) {
112
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
113
+ });
114
+ }
115
+ return target;
116
+ }
117
+ function _sliced_to_array(arr, i) {
118
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
119
+ }
120
+ function _unsupported_iterable_to_array(o, minLen) {
121
+ if (!o) return;
122
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
123
+ var n = Object.prototype.toString.call(o).slice(8, -1);
124
+ if (n === "Object" && o.constructor) n = o.constructor.name;
125
+ if (n === "Map" || n === "Set") return Array.from(n);
126
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
127
+ }
128
+ function _ts_generator(thisArg, body) {
129
+ var f, y, t, _ = {
130
+ label: 0,
131
+ sent: function() {
132
+ if (t[0] & 1) throw t[1];
133
+ return t[1];
134
+ },
135
+ trys: [],
136
+ ops: []
137
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
138
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
139
+ return this;
140
+ }), g;
141
+ function verb(n) {
142
+ return function(v) {
143
+ return step([
144
+ n,
145
+ v
146
+ ]);
147
+ };
148
+ }
149
+ function step(op) {
150
+ if (f) throw new TypeError("Generator is already executing.");
151
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
152
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
153
+ if (y = 0, t) op = [
154
+ op[0] & 2,
155
+ t.value
156
+ ];
157
+ switch(op[0]){
158
+ case 0:
159
+ case 1:
160
+ t = op;
161
+ break;
162
+ case 4:
163
+ _.label++;
164
+ return {
165
+ value: op[1],
166
+ done: false
167
+ };
168
+ case 5:
169
+ _.label++;
170
+ y = op[1];
171
+ op = [
172
+ 0
173
+ ];
174
+ continue;
175
+ case 7:
176
+ op = _.ops.pop();
177
+ _.trys.pop();
178
+ continue;
179
+ default:
180
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
181
+ _ = 0;
182
+ continue;
183
+ }
184
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
185
+ _.label = op[1];
186
+ break;
187
+ }
188
+ if (op[0] === 6 && _.label < t[1]) {
189
+ _.label = t[1];
190
+ t = op;
191
+ break;
192
+ }
193
+ if (t && _.label < t[2]) {
194
+ _.label = t[2];
195
+ _.ops.push(op);
196
+ break;
197
+ }
198
+ if (t[2]) _.ops.pop();
199
+ _.trys.pop();
200
+ continue;
201
+ }
202
+ op = body.call(thisArg, _);
203
+ } catch (e) {
204
+ op = [
205
+ 6,
206
+ e
207
+ ];
208
+ y = 0;
209
+ } finally{
210
+ f = t = 0;
211
+ }
212
+ if (op[0] & 5) throw op[1];
213
+ return {
214
+ value: op[0] ? op[1] : void 0,
215
+ done: true
216
+ };
217
+ }
218
+ }
219
+ import process from 'process';
220
+ import * as fs from 'fs';
221
+ import * as path from 'path';
222
+ import * as os from 'os';
223
+ import caz from 'caz';
224
+ import { isText } from 'istextorbinary';
225
+ import * as http from 'http';
226
+ import * as https from 'https';
227
+ import { URL } from 'url';
228
+ import { createMinimalProject } from './test-utils.js';
229
+ // Singleton API client instance
230
+ export var apiClient = {
231
+ fetch: function(apiPath, options) {
232
+ return _async_to_generator(function() {
233
+ var port, baseUrl, fullUrl;
234
+ return _ts_generator(this, function(_state) {
235
+ port = process.env.POSITRONIC_PORT || '8787';
236
+ baseUrl = "http://localhost:".concat(port);
237
+ fullUrl = "".concat(baseUrl).concat(apiPath.startsWith('/') ? apiPath : '/' + apiPath);
238
+ return [
239
+ 2,
240
+ fetch(fullUrl, options)
241
+ ];
242
+ });
243
+ })();
244
+ }
245
+ };
246
+ export function generateProject(projectName, projectDir) {
247
+ return _async_to_generator(function() {
248
+ var devPath, newProjectTemplatePath, cazOptions, originalNewProjectPkg, copiedNewProjectPkg;
249
+ return _ts_generator(this, function(_state) {
250
+ switch(_state.label){
251
+ case 0:
252
+ if (!(process.env.NODE_ENV === 'test')) return [
253
+ 3,
254
+ 2
255
+ ];
256
+ return [
257
+ 4,
258
+ createMinimalProject(projectDir)
259
+ ];
260
+ case 1:
261
+ _state.sent();
262
+ return [
263
+ 2
264
+ ];
265
+ case 2:
266
+ devPath = process.env.POSITRONIC_LOCAL_PATH;
267
+ newProjectTemplatePath = '@positronic/template-new-project';
268
+ cazOptions = {
269
+ name: projectName
270
+ };
271
+ _state.label = 3;
272
+ case 3:
273
+ _state.trys.push([
274
+ 3,
275
+ ,
276
+ 5,
277
+ 6
278
+ ]);
279
+ if (devPath) {
280
+ // Copying templates, why you ask?
281
+ // Well because when caz runs if you pass it a path to the template module
282
+ // (e.g. for development environment setting POSITRONIC_LOCAL_PATH)
283
+ // it runs npm install --production in the template directory. This is a problem
284
+ // in our monorepo because this messes up the node_modules at the root of the
285
+ // monorepo which then causes the tests to fail. Also ny time I was generating a new
286
+ // project it was a pain to have to run npm install over and over again just
287
+ // to get back to a good state.
288
+ originalNewProjectPkg = path.resolve(devPath, 'packages', 'template-new-project');
289
+ copiedNewProjectPkg = fs.mkdtempSync(path.join(os.tmpdir(), 'positronic-newproj-'));
290
+ fs.cpSync(originalNewProjectPkg, copiedNewProjectPkg, {
291
+ recursive: true
292
+ });
293
+ newProjectTemplatePath = copiedNewProjectPkg;
294
+ cazOptions = {
295
+ name: projectName,
296
+ install: true,
297
+ pm: 'npm'
298
+ };
299
+ }
300
+ // In test or CI environments, skip interactive prompts and dependency installation
301
+ if (process.env.NODE_ENV === 'test') {
302
+ cazOptions = _object_spread_props(_object_spread({}, cazOptions), {
303
+ backend: 'none',
304
+ install: false,
305
+ pm: 'npm'
306
+ });
307
+ }
308
+ return [
309
+ 4,
310
+ caz.default(newProjectTemplatePath, projectDir, _object_spread_props(_object_spread({}, cazOptions), {
311
+ force: false
312
+ }))
313
+ ];
314
+ case 4:
315
+ _state.sent();
316
+ return [
317
+ 3,
318
+ 6
319
+ ];
320
+ case 5:
321
+ // Clean up the temporary copied new project package
322
+ if (devPath) {
323
+ fs.rmSync(newProjectTemplatePath, {
324
+ recursive: true,
325
+ force: true,
326
+ maxRetries: 3
327
+ });
328
+ }
329
+ return [
330
+ 7
331
+ ];
332
+ case 6:
333
+ return [
334
+ 2
335
+ ];
336
+ }
337
+ });
338
+ })();
339
+ }
340
+ export function scanLocalResources(resourcesDir) {
341
+ var localResources = [];
342
+ var scanDirectory = function(dir, baseDir) {
343
+ var entries = fs.readdirSync(dir, {
344
+ withFileTypes: true
345
+ });
346
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
347
+ try {
348
+ for(var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
349
+ var entry = _step.value;
350
+ var fullPath = path.join(dir, entry.name);
351
+ if (entry.isDirectory()) {
352
+ // Recursively scan subdirectories
353
+ scanDirectory(fullPath, baseDir);
354
+ } else if (entry.isFile()) {
355
+ // Calculate relative path from resources directory
356
+ var relativePath = path.relative(baseDir, fullPath);
357
+ // Use forward slashes for consistency across platforms
358
+ var key = relativePath.replace(/\\/g, '/');
359
+ // Determine file type using istextorbinary
360
+ // It checks both filename and content (first few bytes)
361
+ var type = isText(entry.name, fs.readFileSync(fullPath)) ? 'text' : 'binary';
362
+ localResources.push({
363
+ key: key,
364
+ path: fullPath,
365
+ type: type
366
+ });
367
+ }
368
+ }
369
+ } catch (err) {
370
+ _didIteratorError = true;
371
+ _iteratorError = err;
372
+ } finally{
373
+ try {
374
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
375
+ _iterator.return();
376
+ }
377
+ } finally{
378
+ if (_didIteratorError) {
379
+ throw _iteratorError;
380
+ }
381
+ }
382
+ }
383
+ };
384
+ scanDirectory(resourcesDir, resourcesDir);
385
+ return localResources;
386
+ }
387
+ /**
388
+ * Core resource sync logic without UI dependencies
389
+ */ export function syncResources(_0, _1) {
390
+ return _async_to_generator(function(projectRootPath) {
391
+ var client, onProgress, resourcesDir, localResources, response, errorText, data, serverResourceMap, localResourceKeys, uploadCount, skipCount, errorCount, deleteCount, errors, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, resource, fileStats, serverResource, shouldUpload, localModTime, fileContent, formData, uploadResponse, errorText1, error, err, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, _step_value, key, serverResource1, deleteResponse, errorText2, error1, err;
392
+ var _arguments = arguments;
393
+ return _ts_generator(this, function(_state) {
394
+ switch(_state.label){
395
+ case 0:
396
+ client = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : apiClient, onProgress = _arguments.length > 2 ? _arguments[2] : void 0;
397
+ resourcesDir = path.join(projectRootPath, 'resources');
398
+ // Ensure resources directory exists
399
+ if (!fs.existsSync(resourcesDir)) {
400
+ fs.mkdirSync(resourcesDir, {
401
+ recursive: true
402
+ });
403
+ }
404
+ localResources = scanLocalResources(resourcesDir);
405
+ return [
406
+ 4,
407
+ client.fetch('/resources')
408
+ ];
409
+ case 1:
410
+ response = _state.sent();
411
+ if (!!response.ok) return [
412
+ 3,
413
+ 3
414
+ ];
415
+ return [
416
+ 4,
417
+ response.text()
418
+ ];
419
+ case 2:
420
+ errorText = _state.sent();
421
+ throw new Error("Failed to fetch resources: ".concat(response.status, " ").concat(errorText));
422
+ case 3:
423
+ return [
424
+ 4,
425
+ response.json()
426
+ ];
427
+ case 4:
428
+ data = _state.sent();
429
+ serverResourceMap = new Map(data.resources.map(function(r) {
430
+ return [
431
+ r.key,
432
+ r
433
+ ];
434
+ }));
435
+ // Create a set of local resource keys for easy lookup
436
+ localResourceKeys = new Set(localResources.map(function(r) {
437
+ return r.key;
438
+ }));
439
+ uploadCount = 0;
440
+ skipCount = 0;
441
+ errorCount = 0;
442
+ deleteCount = 0;
443
+ errors = [];
444
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
445
+ _state.label = 5;
446
+ case 5:
447
+ _state.trys.push([
448
+ 5,
449
+ 16,
450
+ 17,
451
+ 18
452
+ ]);
453
+ _iterator = localResources[Symbol.iterator]();
454
+ _state.label = 6;
455
+ case 6:
456
+ if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
457
+ 3,
458
+ 15
459
+ ];
460
+ resource = _step.value;
461
+ // Report progress for checking
462
+ if (onProgress) {
463
+ onProgress({
464
+ currentFile: resource.key,
465
+ action: 'checking',
466
+ stats: {
467
+ uploadCount: uploadCount,
468
+ skipCount: skipCount,
469
+ errorCount: errorCount,
470
+ totalCount: localResources.length,
471
+ deleteCount: deleteCount,
472
+ errors: errors
473
+ }
474
+ });
475
+ }
476
+ fileStats = fs.statSync(resource.path);
477
+ serverResource = serverResourceMap.get(resource.key);
478
+ // Check if we need to upload (new or modified)
479
+ shouldUpload = !serverResource;
480
+ if (serverResource && serverResource.size !== fileStats.size) {
481
+ // Size mismatch indicates file has changed
482
+ shouldUpload = true;
483
+ } else if (serverResource) {
484
+ // For same-size files, check modification time if available
485
+ localModTime = fileStats.mtime.toISOString();
486
+ if (localModTime > serverResource.lastModified) {
487
+ shouldUpload = true;
488
+ }
489
+ }
490
+ if (!shouldUpload) return [
491
+ 3,
492
+ 13
493
+ ];
494
+ _state.label = 7;
495
+ case 7:
496
+ _state.trys.push([
497
+ 7,
498
+ 11,
499
+ ,
500
+ 12
501
+ ]);
502
+ // Report progress for uploading
503
+ if (onProgress) {
504
+ onProgress({
505
+ currentFile: resource.key,
506
+ action: 'uploading',
507
+ stats: {
508
+ uploadCount: uploadCount,
509
+ skipCount: skipCount,
510
+ errorCount: errorCount,
511
+ totalCount: localResources.length,
512
+ deleteCount: deleteCount,
513
+ errors: errors
514
+ }
515
+ });
516
+ }
517
+ fileContent = fs.readFileSync(resource.path);
518
+ formData = new FormData();
519
+ formData.append('file', new Blob([
520
+ fileContent
521
+ ]), path.basename(resource.path));
522
+ formData.append('type', resource.type);
523
+ formData.append('path', resource.key);
524
+ formData.append('key', resource.key);
525
+ formData.append('local', 'true');
526
+ return [
527
+ 4,
528
+ client.fetch('/resources', {
529
+ method: 'POST',
530
+ body: formData
531
+ })
532
+ ];
533
+ case 8:
534
+ uploadResponse = _state.sent();
535
+ if (!!uploadResponse.ok) return [
536
+ 3,
537
+ 10
538
+ ];
539
+ return [
540
+ 4,
541
+ uploadResponse.text()
542
+ ];
543
+ case 9:
544
+ errorText1 = _state.sent();
545
+ throw new Error("Upload failed: ".concat(uploadResponse.status, " ").concat(errorText1));
546
+ case 10:
547
+ uploadCount++;
548
+ return [
549
+ 3,
550
+ 12
551
+ ];
552
+ case 11:
553
+ error = _state.sent();
554
+ errorCount++;
555
+ errors.push({
556
+ file: resource.key,
557
+ message: error.message || 'Unknown error'
558
+ });
559
+ return [
560
+ 3,
561
+ 12
562
+ ];
563
+ case 12:
564
+ return [
565
+ 3,
566
+ 14
567
+ ];
568
+ case 13:
569
+ skipCount++;
570
+ _state.label = 14;
571
+ case 14:
572
+ _iteratorNormalCompletion = true;
573
+ return [
574
+ 3,
575
+ 6
576
+ ];
577
+ case 15:
578
+ return [
579
+ 3,
580
+ 18
581
+ ];
582
+ case 16:
583
+ err = _state.sent();
584
+ _didIteratorError = true;
585
+ _iteratorError = err;
586
+ return [
587
+ 3,
588
+ 18
589
+ ];
590
+ case 17:
591
+ try {
592
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
593
+ _iterator.return();
594
+ }
595
+ } finally{
596
+ if (_didIteratorError) {
597
+ throw _iteratorError;
598
+ }
599
+ }
600
+ return [
601
+ 7
602
+ ];
603
+ case 18:
604
+ _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
605
+ _state.label = 19;
606
+ case 19:
607
+ _state.trys.push([
608
+ 19,
609
+ 28,
610
+ 29,
611
+ 30
612
+ ]);
613
+ _iterator1 = serverResourceMap[Symbol.iterator]();
614
+ _state.label = 20;
615
+ case 20:
616
+ if (!!(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done)) return [
617
+ 3,
618
+ 27
619
+ ];
620
+ _step_value = _sliced_to_array(_step1.value, 2), key = _step_value[0], serverResource1 = _step_value[1];
621
+ if (!(serverResource1.local && !localResourceKeys.has(key))) return [
622
+ 3,
623
+ 26
624
+ ];
625
+ _state.label = 21;
626
+ case 21:
627
+ _state.trys.push([
628
+ 21,
629
+ 25,
630
+ ,
631
+ 26
632
+ ]);
633
+ // Report progress for deleting
634
+ if (onProgress) {
635
+ onProgress({
636
+ currentFile: key,
637
+ action: 'deleting',
638
+ stats: {
639
+ uploadCount: uploadCount,
640
+ skipCount: skipCount,
641
+ errorCount: errorCount,
642
+ totalCount: localResources.length,
643
+ deleteCount: deleteCount,
644
+ errors: errors
645
+ }
646
+ });
647
+ }
648
+ return [
649
+ 4,
650
+ client.fetch("/resources/".concat(encodeURIComponent(key)), {
651
+ method: 'DELETE'
652
+ })
653
+ ];
654
+ case 22:
655
+ deleteResponse = _state.sent();
656
+ if (!(!deleteResponse.ok && deleteResponse.status !== 404)) return [
657
+ 3,
658
+ 24
659
+ ];
660
+ return [
661
+ 4,
662
+ deleteResponse.text()
663
+ ];
664
+ case 23:
665
+ errorText2 = _state.sent();
666
+ throw new Error("Delete failed: ".concat(deleteResponse.status, " ").concat(errorText2));
667
+ case 24:
668
+ deleteCount++;
669
+ return [
670
+ 3,
671
+ 26
672
+ ];
673
+ case 25:
674
+ error1 = _state.sent();
675
+ errorCount++;
676
+ errors.push({
677
+ file: key,
678
+ message: "Failed to delete: ".concat(error1.message || 'Unknown error')
679
+ });
680
+ return [
681
+ 3,
682
+ 26
683
+ ];
684
+ case 26:
685
+ _iteratorNormalCompletion1 = true;
686
+ return [
687
+ 3,
688
+ 20
689
+ ];
690
+ case 27:
691
+ return [
692
+ 3,
693
+ 30
694
+ ];
695
+ case 28:
696
+ err = _state.sent();
697
+ _didIteratorError1 = true;
698
+ _iteratorError1 = err;
699
+ return [
700
+ 3,
701
+ 30
702
+ ];
703
+ case 29:
704
+ try {
705
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
706
+ _iterator1.return();
707
+ }
708
+ } finally{
709
+ if (_didIteratorError1) {
710
+ throw _iteratorError1;
711
+ }
712
+ }
713
+ return [
714
+ 7
715
+ ];
716
+ case 30:
717
+ return [
718
+ 2,
719
+ {
720
+ uploadCount: uploadCount,
721
+ skipCount: skipCount,
722
+ errorCount: errorCount,
723
+ totalCount: localResources.length,
724
+ deleteCount: deleteCount,
725
+ errors: errors
726
+ }
727
+ ];
728
+ }
729
+ });
730
+ }).apply(this, arguments);
731
+ }
732
+ /**
733
+ * Check if a string is a valid JavaScript identifier
734
+ */ function isValidJSIdentifier(name) {
735
+ // Must start with letter, underscore, or dollar sign
736
+ // Can contain letters, digits, underscores, dollar signs
737
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
738
+ }
739
+ /**
740
+ * Build TypeScript structure from resource tree
741
+ */ function buildTypeStructure(node) {
742
+ if (!node.children) return [];
743
+ var properties = [];
744
+ var processedNames = new Set();
745
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
746
+ try {
747
+ for(var _iterator = Object.entries(node.children)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
748
+ var _step_value = _sliced_to_array(_step.value, 2), name = _step_value[0], child = _step_value[1];
749
+ if (processedNames.has(name)) continue;
750
+ if (child.type) {
751
+ // File resource
752
+ var resourceType = child.type === 'text' ? 'TextResource' : 'BinaryResource';
753
+ properties.push({
754
+ name: name,
755
+ type: resourceType
756
+ });
757
+ processedNames.add(name);
758
+ if (child.fullName) {
759
+ processedNames.add(child.fullName);
760
+ }
761
+ } else if (child.children) {
762
+ // Directory with nested resources
763
+ var nestedProps = buildTypeStructure(child);
764
+ if (nestedProps.length > 0) {
765
+ properties.push({
766
+ name: name,
767
+ type: {
768
+ properties: nestedProps
769
+ }
770
+ });
771
+ processedNames.add(name);
772
+ }
773
+ }
774
+ }
775
+ } catch (err) {
776
+ _didIteratorError = true;
777
+ _iteratorError = err;
778
+ } finally{
779
+ try {
780
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
781
+ _iterator.return();
782
+ }
783
+ } finally{
784
+ if (_didIteratorError) {
785
+ throw _iteratorError;
786
+ }
787
+ }
788
+ }
789
+ return properties;
790
+ }
791
+ /**
792
+ * Render TypeScript from structure
793
+ */ function renderTypeScript(properties) {
794
+ var indent = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : ' ';
795
+ return properties.map(function(prop) {
796
+ if (typeof prop.type === 'string') {
797
+ return "".concat(indent).concat(prop.name, ": ").concat(prop.type, ";");
798
+ } else {
799
+ var nestedContent = renderTypeScript(prop.type.properties, indent + ' ');
800
+ return "".concat(indent).concat(prop.name, ": {\n").concat(nestedContent, "\n").concat(indent, "};");
801
+ }
802
+ }).join('\n');
803
+ }
804
+ /**
805
+ * Generate TypeScript declarations for resources
806
+ */ function generateResourceTypes(resources) {
807
+ var root = {
808
+ children: {}
809
+ };
810
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
811
+ try {
812
+ // Build the tree structure
813
+ for(var _iterator = resources[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
814
+ var resource = _step.value;
815
+ var parts = resource.key.split('/');
816
+ var current = root;
817
+ for(var i = 0; i < parts.length; i++){
818
+ var part = parts[i];
819
+ var isLeaf = i === parts.length - 1;
820
+ if (!current.children) {
821
+ current.children = {};
822
+ }
823
+ if (isLeaf) {
824
+ var resourceNode = {
825
+ type: resource.type,
826
+ fullName: part
827
+ };
828
+ if (isValidJSIdentifier(part)) {
829
+ current.children[part] = resourceNode;
830
+ }
831
+ var withoutExt = part.replace(/\.[^/.]+$/, '');
832
+ if (withoutExt !== part && isValidJSIdentifier(withoutExt)) {
833
+ if (!current.children[withoutExt]) {
834
+ current.children[withoutExt] = resourceNode;
835
+ }
836
+ }
837
+ } else {
838
+ if (isValidJSIdentifier(part)) {
839
+ if (!current.children[part]) {
840
+ current.children[part] = {
841
+ children: {}
842
+ };
843
+ }
844
+ current = current.children[part];
845
+ } else {
846
+ break;
847
+ }
848
+ }
849
+ }
850
+ }
851
+ } catch (err) {
852
+ _didIteratorError = true;
853
+ _iteratorError = err;
854
+ } finally{
855
+ try {
856
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
857
+ _iterator.return();
858
+ }
859
+ } finally{
860
+ if (_didIteratorError) {
861
+ throw _iteratorError;
862
+ }
863
+ }
864
+ }
865
+ var typeStructure = buildTypeStructure(root);
866
+ var interfaceContent = renderTypeScript(typeStructure);
867
+ return "// Generated by Positronic CLI\n// This file provides TypeScript types for your resources\n\ndeclare module '@positronic/core' {\n interface TextResource {\n load(): Promise<string>;\n }\n\n interface BinaryResource {\n load(): Promise<Buffer>;\n }\n\n interface Resources {\n // Method signatures for loading resources by path\n loadText(path: string): Promise<string>;\n loadBinary(path: string): Promise<Buffer>;\n\n // Resource properties accessible via dot notation\n".concat(interfaceContent, "\n }\n}\n\nexport {}; // Make this a module\n");
868
+ }
869
+ /**
870
+ * Core type generation logic without UI dependencies
871
+ */ export function generateTypes(_0) {
872
+ return _async_to_generator(function(projectRootPath) {
873
+ var client, typesFilePath, response, errorText, data, typeDefinitions;
874
+ var _arguments = arguments;
875
+ return _ts_generator(this, function(_state) {
876
+ switch(_state.label){
877
+ case 0:
878
+ client = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : apiClient;
879
+ typesFilePath = path.join(projectRootPath, 'resources.d.ts');
880
+ return [
881
+ 4,
882
+ client.fetch('/resources')
883
+ ];
884
+ case 1:
885
+ response = _state.sent();
886
+ if (!!response.ok) return [
887
+ 3,
888
+ 3
889
+ ];
890
+ return [
891
+ 4,
892
+ response.text()
893
+ ];
894
+ case 2:
895
+ errorText = _state.sent();
896
+ throw new Error("Failed to fetch resources: ".concat(response.status, " ").concat(errorText));
897
+ case 3:
898
+ return [
899
+ 4,
900
+ response.json()
901
+ ];
902
+ case 4:
903
+ data = _state.sent();
904
+ typeDefinitions = generateResourceTypes(data.resources);
905
+ fs.writeFileSync(typesFilePath, typeDefinitions, 'utf-8');
906
+ return [
907
+ 2,
908
+ path.relative(process.cwd(), typesFilePath)
909
+ ];
910
+ }
911
+ });
912
+ }).apply(this, arguments);
913
+ }
914
+ /**
915
+ * Wait for resources to stabilize (indicating initial sync is complete)
916
+ */ function waitForResources(maxWaitMs, startTime) {
917
+ return _async_to_generator(function() {
918
+ var lastCount, stableCount, response, data, e;
919
+ return _ts_generator(this, function(_state) {
920
+ switch(_state.label){
921
+ case 0:
922
+ lastCount = -1;
923
+ stableCount = 0;
924
+ _state.label = 1;
925
+ case 1:
926
+ if (!(Date.now() - startTime < maxWaitMs)) return [
927
+ 3,
928
+ 9
929
+ ];
930
+ _state.label = 2;
931
+ case 2:
932
+ _state.trys.push([
933
+ 2,
934
+ 6,
935
+ ,
936
+ 7
937
+ ]);
938
+ return [
939
+ 4,
940
+ apiClient.fetch("/resources")
941
+ ];
942
+ case 3:
943
+ response = _state.sent();
944
+ if (!response.ok) return [
945
+ 3,
946
+ 5
947
+ ];
948
+ return [
949
+ 4,
950
+ response.json()
951
+ ];
952
+ case 4:
953
+ data = _state.sent();
954
+ // If the count hasn't changed for 3 checks, we consider it stable
955
+ if (data.count === lastCount) {
956
+ stableCount++;
957
+ if (stableCount >= 3) {
958
+ return [
959
+ 2,
960
+ true
961
+ ]; // Resources are stable
962
+ }
963
+ } else {
964
+ lastCount = data.count;
965
+ stableCount = 0;
966
+ }
967
+ _state.label = 5;
968
+ case 5:
969
+ return [
970
+ 3,
971
+ 7
972
+ ];
973
+ case 6:
974
+ e = _state.sent();
975
+ return [
976
+ 3,
977
+ 7
978
+ ];
979
+ case 7:
980
+ return [
981
+ 4,
982
+ new Promise(function(resolve) {
983
+ return setTimeout(resolve, 100);
984
+ })
985
+ ];
986
+ case 8:
987
+ _state.sent();
988
+ return [
989
+ 3,
990
+ 1
991
+ ];
992
+ case 9:
993
+ return [
994
+ 2,
995
+ false
996
+ ];
997
+ }
998
+ });
999
+ })();
1000
+ }
1001
+ /**
1002
+ * Helper function to wait for server to be ready
1003
+ */ export function waitUntilReady(port) {
1004
+ var maxWaitMs = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 5000;
1005
+ return _async_to_generator(function() {
1006
+ var serverPort, startTime, response, status, e;
1007
+ return _ts_generator(this, function(_state) {
1008
+ switch(_state.label){
1009
+ case 0:
1010
+ serverPort = port || Number(process.env.POSITRONIC_PORT) || 8787;
1011
+ startTime = Date.now();
1012
+ _state.label = 1;
1013
+ case 1:
1014
+ if (!(Date.now() - startTime < maxWaitMs)) return [
1015
+ 3,
1016
+ 9
1017
+ ];
1018
+ _state.label = 2;
1019
+ case 2:
1020
+ _state.trys.push([
1021
+ 2,
1022
+ 6,
1023
+ ,
1024
+ 7
1025
+ ]);
1026
+ return [
1027
+ 4,
1028
+ apiClient.fetch("/status")
1029
+ ];
1030
+ case 3:
1031
+ response = _state.sent();
1032
+ if (!response.ok) return [
1033
+ 3,
1034
+ 5
1035
+ ];
1036
+ return [
1037
+ 4,
1038
+ response.json()
1039
+ ];
1040
+ case 4:
1041
+ status = _state.sent();
1042
+ if (status.ready) {
1043
+ return [
1044
+ 3,
1045
+ 9
1046
+ ]; // HTTP server is ready
1047
+ }
1048
+ _state.label = 5;
1049
+ case 5:
1050
+ return [
1051
+ 3,
1052
+ 7
1053
+ ];
1054
+ case 6:
1055
+ e = _state.sent();
1056
+ return [
1057
+ 3,
1058
+ 7
1059
+ ];
1060
+ case 7:
1061
+ return [
1062
+ 4,
1063
+ new Promise(function(resolve) {
1064
+ return setTimeout(resolve, 100);
1065
+ })
1066
+ ];
1067
+ case 8:
1068
+ _state.sent();
1069
+ return [
1070
+ 3,
1071
+ 1
1072
+ ];
1073
+ case 9:
1074
+ // Now wait for resources to stabilize (indicating initial sync is done)
1075
+ return [
1076
+ 2,
1077
+ waitForResources(maxWaitMs, startTime)
1078
+ ];
1079
+ }
1080
+ });
1081
+ })();
1082
+ }
1083
+ /**
1084
+ * Upload a file using presigned URL for large files
1085
+ * This function is used by the `px resources upload` command to upload files
1086
+ * directly to R2 storage, bypassing the 100MB Worker limit.
1087
+ *
1088
+ * @param filePath - Path to the file to upload
1089
+ * @param customKey - The key (path) where the file will be stored in R2
1090
+ * @param client - Optional API client (defaults to singleton)
1091
+ * @param onProgress - Optional progress callback
1092
+ * @param signal - Optional AbortSignal for cancellation
1093
+ */ export function uploadFileWithPresignedUrl(_0, _1, _2, _3) {
1094
+ return _async_to_generator(function(filePath, customKey) {
1095
+ var client, onProgress, signal, stats, fileName, fileType, fileContent, presignedResponse, errorText, errorMessage, errorData, _ref, url, method, requiredHeaders, fileContent1, parsedUrl, httpModule, uploadResponse;
1096
+ var _arguments = arguments;
1097
+ return _ts_generator(this, function(_state) {
1098
+ switch(_state.label){
1099
+ case 0:
1100
+ client = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : apiClient, onProgress = _arguments.length > 3 ? _arguments[3] : void 0, signal = _arguments.length > 4 ? _arguments[4] : void 0;
1101
+ // Get file info
1102
+ stats = fs.statSync(filePath);
1103
+ fileName = path.basename(filePath);
1104
+ if (stats.size < 1024 * 1024) {
1105
+ // 1MB
1106
+ fileContent = fs.readFileSync(filePath);
1107
+ fileType = isText(fileName, fileContent) ? 'text' : 'binary';
1108
+ } else {
1109
+ // For large files, use extension-based detection
1110
+ fileType = isText(fileName) ? 'text' : 'binary';
1111
+ }
1112
+ return [
1113
+ 4,
1114
+ client.fetch('/resources/presigned-link', {
1115
+ method: 'POST',
1116
+ headers: {
1117
+ 'Content-Type': 'application/json'
1118
+ },
1119
+ body: JSON.stringify({
1120
+ key: customKey,
1121
+ type: fileType,
1122
+ size: stats.size
1123
+ })
1124
+ })
1125
+ ];
1126
+ case 1:
1127
+ presignedResponse = _state.sent();
1128
+ if (!!presignedResponse.ok) return [
1129
+ 3,
1130
+ 3
1131
+ ];
1132
+ return [
1133
+ 4,
1134
+ presignedResponse.text()
1135
+ ];
1136
+ case 2:
1137
+ errorText = _state.sent();
1138
+ errorMessage = "Failed to get presigned URL: ".concat(presignedResponse.status);
1139
+ // Parse error response if it's JSON
1140
+ try {
1141
+ errorData = JSON.parse(errorText);
1142
+ if (errorData.error) {
1143
+ errorMessage = errorData.error;
1144
+ }
1145
+ } catch (e) {
1146
+ errorMessage += " ".concat(errorText);
1147
+ }
1148
+ throw new Error(errorMessage);
1149
+ case 3:
1150
+ return [
1151
+ 4,
1152
+ presignedResponse.json()
1153
+ ];
1154
+ case 4:
1155
+ _ref = _state.sent(), url = _ref.url, method = _ref.method;
1156
+ // Headers that must be included in the upload to match the presigned URL signature
1157
+ requiredHeaders = {
1158
+ 'x-amz-meta-type': fileType,
1159
+ 'x-amz-meta-local': 'false'
1160
+ };
1161
+ if (!(stats.size > 10 * 1024 * 1024)) return [
1162
+ 3,
1163
+ 6
1164
+ ];
1165
+ // 10MB
1166
+ return [
1167
+ 4,
1168
+ uploadLargeFileWithProgress(filePath, url, method, stats.size, requiredHeaders, onProgress, signal)
1169
+ ];
1170
+ case 5:
1171
+ _state.sent();
1172
+ return [
1173
+ 3,
1174
+ 8
1175
+ ];
1176
+ case 6:
1177
+ // For small files, use simple upload
1178
+ fileContent1 = fs.readFileSync(filePath);
1179
+ // Use native http/https for the upload
1180
+ parsedUrl = new URL(url);
1181
+ httpModule = parsedUrl.protocol === 'https:' ? https : http;
1182
+ return [
1183
+ 4,
1184
+ new Promise(function(resolve, reject) {
1185
+ var requestOptions = {
1186
+ hostname: parsedUrl.hostname,
1187
+ port: parseInt(parsedUrl.port || (parsedUrl.protocol === 'https:' ? '443' : '80'), 10),
1188
+ path: parsedUrl.pathname + parsedUrl.search,
1189
+ method: method,
1190
+ headers: _object_spread_props(_object_spread({}, requiredHeaders), {
1191
+ 'Content-Length': fileContent1.length.toString()
1192
+ })
1193
+ };
1194
+ var req = httpModule.request(requestOptions, function(res) {
1195
+ var chunks = [];
1196
+ res.on('data', function(chunk) {
1197
+ chunks.push(chunk);
1198
+ });
1199
+ res.on('end', function() {
1200
+ var responseBody = Buffer.concat(chunks);
1201
+ resolve(new Response(responseBody, {
1202
+ status: res.statusCode,
1203
+ statusText: res.statusMessage,
1204
+ headers: Object.fromEntries(Object.entries(res.headers).map(function(param) {
1205
+ var _param = _sliced_to_array(param, 2), key = _param[0], value = _param[1];
1206
+ return [
1207
+ key,
1208
+ Array.isArray(value) ? value.join(', ') : value || ''
1209
+ ];
1210
+ }))
1211
+ }));
1212
+ });
1213
+ res.on('error', reject);
1214
+ });
1215
+ req.on('error', reject);
1216
+ if (signal) {
1217
+ signal.addEventListener('abort', function() {
1218
+ req.destroy();
1219
+ reject(new Error('AbortError'));
1220
+ });
1221
+ }
1222
+ req.write(fileContent1);
1223
+ req.end();
1224
+ })
1225
+ ];
1226
+ case 7:
1227
+ uploadResponse = _state.sent();
1228
+ if (!uploadResponse.ok) {
1229
+ throw new Error("Failed to upload file: ".concat(uploadResponse.status, " ").concat(uploadResponse.statusText));
1230
+ }
1231
+ _state.label = 8;
1232
+ case 8:
1233
+ return [
1234
+ 2
1235
+ ];
1236
+ }
1237
+ });
1238
+ }).apply(this, arguments);
1239
+ }
1240
+ /**
1241
+ * Stream upload large file with progress tracking
1242
+ * Uses Node.js https module for true streaming without loading entire file into memory
1243
+ */ function uploadLargeFileWithProgress(filePath, url, method, totalSize, requiredHeaders, onProgress, signal) {
1244
+ return _async_to_generator(function() {
1245
+ var parsedUrl, httpModule;
1246
+ return _ts_generator(this, function(_state) {
1247
+ parsedUrl = new URL(url);
1248
+ httpModule = parsedUrl.protocol === 'https:' ? https : http;
1249
+ return [
1250
+ 2,
1251
+ new Promise(function(resolve, reject) {
1252
+ // Abort handler
1253
+ var onAbort = function() {
1254
+ req.destroy();
1255
+ reject(new Error('AbortError'));
1256
+ };
1257
+ if (signal) {
1258
+ signal.addEventListener('abort', onAbort);
1259
+ }
1260
+ var options = {
1261
+ hostname: parsedUrl.hostname,
1262
+ port: parsedUrl.port ? parseInt(parsedUrl.port, 10) : undefined,
1263
+ path: parsedUrl.pathname + parsedUrl.search,
1264
+ method: method,
1265
+ headers: _object_spread_props(_object_spread({}, requiredHeaders), {
1266
+ 'Content-Length': totalSize.toString()
1267
+ })
1268
+ };
1269
+ var req = httpModule.request(options, function(res) {
1270
+ var responseBody = '';
1271
+ res.on('data', function(chunk) {
1272
+ responseBody += chunk.toString();
1273
+ });
1274
+ res.on('end', function() {
1275
+ if (signal) {
1276
+ signal.removeEventListener('abort', onAbort);
1277
+ }
1278
+ if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
1279
+ resolve();
1280
+ } else {
1281
+ reject(new Error("Failed to upload file: ".concat(res.statusCode, " ").concat(res.statusMessage, ". Response: ").concat(responseBody)));
1282
+ }
1283
+ });
1284
+ });
1285
+ req.on('error', function(err) {
1286
+ if (signal) {
1287
+ signal.removeEventListener('abort', onAbort);
1288
+ }
1289
+ reject(err);
1290
+ });
1291
+ // Stream the file directly to the request
1292
+ var fileStream = fs.createReadStream(filePath);
1293
+ var uploadedBytes = 0;
1294
+ fileStream.on('data', function(chunk) {
1295
+ var chunkLength = Buffer.isBuffer(chunk) ? chunk.length : Buffer.byteLength(chunk);
1296
+ uploadedBytes += chunkLength;
1297
+ if (onProgress) {
1298
+ onProgress({
1299
+ loaded: uploadedBytes,
1300
+ total: totalSize,
1301
+ percentage: Math.round(uploadedBytes / totalSize * 100)
1302
+ });
1303
+ }
1304
+ });
1305
+ fileStream.on('error', function(err) {
1306
+ req.destroy();
1307
+ reject(err);
1308
+ });
1309
+ // Pipe the file stream to the request
1310
+ fileStream.pipe(req);
1311
+ })
1312
+ ];
1313
+ });
1314
+ })();
1315
+ }