btca-server 2.0.2 → 2.0.3
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/package.json +1 -1
- package/src/agent/agent.test.ts +25 -16
- package/src/agent/service.ts +100 -110
- package/src/collections/service.test.ts +119 -0
- package/src/collections/service.ts +73 -14
- package/src/config/config.test.ts +21 -16
- package/src/config/index.ts +179 -200
- package/src/effect/services.ts +15 -23
- package/src/resources/service.ts +45 -44
- package/src/vfs/virtual-fs.ts +73 -0
package/src/resources/service.ts
CHANGED
|
@@ -41,13 +41,13 @@ export type ResourcesService = {
|
|
|
41
41
|
options?: {
|
|
42
42
|
quiet?: boolean;
|
|
43
43
|
}
|
|
44
|
-
) =>
|
|
45
|
-
|
|
44
|
+
) => Effect.Effect<BtcaFsResource, ResourceError, never>;
|
|
45
|
+
loadPromise: (
|
|
46
46
|
name: string,
|
|
47
47
|
options?: {
|
|
48
48
|
quiet?: boolean;
|
|
49
49
|
}
|
|
50
|
-
) =>
|
|
50
|
+
) => Promise<BtcaFsResource>;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
const normalizeSearchPaths = (definition: GitResource): string[] => {
|
|
@@ -154,55 +154,56 @@ export const resolveResourceDefinition = (
|
|
|
154
154
|
};
|
|
155
155
|
|
|
156
156
|
export const createResourcesService = (config: ConfigServiceShape): ResourcesService => {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (isGitResource(definition)) {
|
|
173
|
-
return yield* Effect.tryPromise({
|
|
174
|
-
try: () =>
|
|
175
|
-
loadGitResource(definitionToGitArgs(definition, config.resourcesDirectory, quiet)),
|
|
176
|
-
catch: (cause) =>
|
|
177
|
-
cause instanceof ResourceError
|
|
178
|
-
? cause
|
|
179
|
-
: new ResourceError({
|
|
180
|
-
message: `Failed to load git resource "${name}"`,
|
|
181
|
-
hint: CommonHints.CLEAR_CACHE,
|
|
182
|
-
cause
|
|
183
|
-
})
|
|
157
|
+
const loadPromise: ResourcesService['loadPromise'] = async (name, options) => {
|
|
158
|
+
const quiet = options?.quiet ?? false;
|
|
159
|
+
const definition = resolveResourceDefinition(name, config.getResource);
|
|
160
|
+
|
|
161
|
+
if (isGitResource(definition)) {
|
|
162
|
+
try {
|
|
163
|
+
return await loadGitResource(
|
|
164
|
+
definitionToGitArgs(definition, config.resourcesDirectory, quiet)
|
|
165
|
+
);
|
|
166
|
+
} catch (cause) {
|
|
167
|
+
if (cause instanceof ResourceError) throw cause;
|
|
168
|
+
throw new ResourceError({
|
|
169
|
+
message: `Failed to load git resource "${name}"`,
|
|
170
|
+
hint: CommonHints.CLEAR_CACHE,
|
|
171
|
+
cause
|
|
184
172
|
});
|
|
185
173
|
}
|
|
174
|
+
}
|
|
186
175
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
cause
|
|
197
|
-
})
|
|
176
|
+
if (isNpmResource(definition)) {
|
|
177
|
+
try {
|
|
178
|
+
return await loadNpmResource(definitionToNpmArgs(definition, config.resourcesDirectory));
|
|
179
|
+
} catch (cause) {
|
|
180
|
+
if (cause instanceof ResourceError) throw cause;
|
|
181
|
+
throw new ResourceError({
|
|
182
|
+
message: `Failed to load npm resource "${name}"`,
|
|
183
|
+
hint: CommonHints.CLEAR_CACHE,
|
|
184
|
+
cause
|
|
198
185
|
});
|
|
199
186
|
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return loadLocalResource(definitionToLocalArgs(definition));
|
|
190
|
+
};
|
|
200
191
|
|
|
201
|
-
|
|
192
|
+
const load: ResourcesService['load'] = (name, options) =>
|
|
193
|
+
Effect.tryPromise({
|
|
194
|
+
try: () => loadPromise(name, options),
|
|
195
|
+
catch: (cause) =>
|
|
196
|
+
cause instanceof ResourceError
|
|
197
|
+
? cause
|
|
198
|
+
: new ResourceError({
|
|
199
|
+
message: `Failed to resolve resource "${name}"`,
|
|
200
|
+
hint: `${CommonHints.LIST_RESOURCES} ${CommonHints.ADD_RESOURCE}`,
|
|
201
|
+
cause
|
|
202
|
+
})
|
|
202
203
|
});
|
|
203
204
|
|
|
204
205
|
return {
|
|
205
|
-
load
|
|
206
|
-
|
|
206
|
+
load,
|
|
207
|
+
loadPromise
|
|
207
208
|
};
|
|
208
209
|
};
|
package/src/vfs/virtual-fs.ts
CHANGED
|
@@ -281,3 +281,76 @@ export const importDirectoryIntoVirtualFs = async (args: {
|
|
|
281
281
|
await mkdirVirtualFs(dest, { recursive: true }, vfsId);
|
|
282
282
|
await walk(base);
|
|
283
283
|
};
|
|
284
|
+
|
|
285
|
+
export const importPathsIntoVirtualFs = async (args: {
|
|
286
|
+
sourcePath: string;
|
|
287
|
+
destinationPath: string;
|
|
288
|
+
relativePaths: readonly string[];
|
|
289
|
+
vfsId?: string;
|
|
290
|
+
}) => {
|
|
291
|
+
const base = path.resolve(args.sourcePath);
|
|
292
|
+
const dest = normalizeVfsPath(args.destinationPath);
|
|
293
|
+
const vfsId = args.vfsId;
|
|
294
|
+
const uniquePaths = Array.from(
|
|
295
|
+
new Set(
|
|
296
|
+
args.relativePaths
|
|
297
|
+
.map((relativePath) => relativePath.trim())
|
|
298
|
+
.filter((relativePath) => relativePath.length > 0 && relativePath !== '.')
|
|
299
|
+
)
|
|
300
|
+
).sort((left, right) => left.localeCompare(right));
|
|
301
|
+
|
|
302
|
+
await mkdirVirtualFs(dest, { recursive: true }, vfsId);
|
|
303
|
+
|
|
304
|
+
for (const relativePath of uniquePaths) {
|
|
305
|
+
const sourcePath = path.join(base, relativePath);
|
|
306
|
+
const destinationPath = normalizeVfsPath(
|
|
307
|
+
posix.join(dest, relativePath.split(path.sep).join('/'))
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
let stat: Awaited<ReturnType<typeof fs.lstat>> | null = null;
|
|
311
|
+
try {
|
|
312
|
+
stat = await fs.lstat(sourcePath);
|
|
313
|
+
} catch {
|
|
314
|
+
stat = null;
|
|
315
|
+
}
|
|
316
|
+
if (!stat) continue;
|
|
317
|
+
|
|
318
|
+
await mkdirVirtualFs(posix.dirname(destinationPath), { recursive: true }, vfsId);
|
|
319
|
+
|
|
320
|
+
if (stat.isDirectory()) {
|
|
321
|
+
await mkdirVirtualFs(destinationPath, { recursive: true }, vfsId);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (stat.isSymbolicLink()) {
|
|
326
|
+
let target: string | null = null;
|
|
327
|
+
try {
|
|
328
|
+
target = await fs.readlink(sourcePath);
|
|
329
|
+
} catch {
|
|
330
|
+
target = null;
|
|
331
|
+
}
|
|
332
|
+
if (!target) continue;
|
|
333
|
+
try {
|
|
334
|
+
await symlinkVirtualFs(target, destinationPath, vfsId);
|
|
335
|
+
} catch {
|
|
336
|
+
// Ignore invalid symlink entries while importing.
|
|
337
|
+
}
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (!stat.isFile()) continue;
|
|
342
|
+
|
|
343
|
+
let buffer: Buffer | null = null;
|
|
344
|
+
try {
|
|
345
|
+
buffer = await fs.readFile(sourcePath);
|
|
346
|
+
} catch {
|
|
347
|
+
buffer = null;
|
|
348
|
+
}
|
|
349
|
+
if (!buffer) continue;
|
|
350
|
+
try {
|
|
351
|
+
await writeVirtualFsFile(destinationPath, buffer, vfsId);
|
|
352
|
+
} catch {
|
|
353
|
+
// Ignore individual file write errors while importing.
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
};
|