resourcexjs 1.7.0 → 2.0.0
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/dist/arp.js +356 -62
- package/dist/arp.js.map +3 -3
- package/dist/index.js +345 -69
- package/dist/index.js.map +3 -3
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -2502,9 +2502,16 @@ import { join } from "node:path";
|
|
|
2502
2502
|
import { readFile, writeFile, mkdir, rm, stat, readdir } from "node:fs/promises";
|
|
2503
2503
|
import { gzip as gzip22, gunzip as gunzip22 } from "node:zlib";
|
|
2504
2504
|
import { promisify as promisify22 } from "node:util";
|
|
2505
|
+
import { homedir as homedir2 } from "node:os";
|
|
2506
|
+
import { join as join2 } from "node:path";
|
|
2507
|
+
import { readFile as readFile2, stat as stat2, readdir as readdir2, mkdir as mkdir2 } from "node:fs/promises";
|
|
2508
|
+
import { execSync } from "node:child_process";
|
|
2505
2509
|
function isRemoteConfig(config) {
|
|
2506
2510
|
return config !== undefined && "endpoint" in config;
|
|
2507
2511
|
}
|
|
2512
|
+
function isGitConfig(config) {
|
|
2513
|
+
return config !== undefined && "type" in config && config.type === "git";
|
|
2514
|
+
}
|
|
2508
2515
|
|
|
2509
2516
|
class ResourceXError3 extends Error {
|
|
2510
2517
|
constructor(message, options) {
|
|
@@ -3974,23 +3981,63 @@ class LocalRegistry {
|
|
|
3974
3981
|
supportType(type) {
|
|
3975
3982
|
this.typeHandler.register(type);
|
|
3976
3983
|
}
|
|
3977
|
-
buildPath(locator) {
|
|
3984
|
+
buildPath(locator, area) {
|
|
3978
3985
|
const rxl = typeof locator === "string" ? parseRXL3(locator) : locator;
|
|
3979
|
-
const
|
|
3986
|
+
const resourceName = rxl.type ? `${rxl.name}.${rxl.type}` : rxl.name;
|
|
3980
3987
|
const version = rxl.version ?? "latest";
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3988
|
+
if (area === "local") {
|
|
3989
|
+
return join(this.basePath, "local", resourceName, version);
|
|
3990
|
+
} else {
|
|
3991
|
+
const domain = rxl.domain ?? "localhost";
|
|
3992
|
+
let path = join(this.basePath, "cache", domain);
|
|
3993
|
+
if (rxl.path) {
|
|
3994
|
+
path = join(path, rxl.path);
|
|
3995
|
+
}
|
|
3996
|
+
return join(path, resourceName, version);
|
|
3984
3997
|
}
|
|
3985
|
-
const resourceName = rxl.type ? `${rxl.name}.${rxl.type}` : rxl.name;
|
|
3986
|
-
return join(path, resourceName, version);
|
|
3987
3998
|
}
|
|
3988
|
-
|
|
3989
|
-
|
|
3999
|
+
isLocalOnlyLocator(locator) {
|
|
4000
|
+
const rxl = typeof locator === "string" ? parseRXL3(locator) : locator;
|
|
4001
|
+
return !rxl.domain || rxl.domain === "localhost";
|
|
4002
|
+
}
|
|
4003
|
+
async existsAt(resourcePath) {
|
|
4004
|
+
const manifestPath = join(resourcePath, "manifest.json");
|
|
4005
|
+
try {
|
|
4006
|
+
await stat(manifestPath);
|
|
4007
|
+
return true;
|
|
4008
|
+
} catch {
|
|
4009
|
+
return false;
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
async findArea(locator) {
|
|
4013
|
+
const localPath = this.buildPath(locator, "local");
|
|
4014
|
+
if (await this.existsAt(localPath)) {
|
|
4015
|
+
return "local";
|
|
4016
|
+
}
|
|
4017
|
+
const cachePath = this.buildPath(locator, "cache");
|
|
4018
|
+
if (await this.existsAt(cachePath)) {
|
|
4019
|
+
return "cache";
|
|
4020
|
+
}
|
|
4021
|
+
return null;
|
|
4022
|
+
}
|
|
4023
|
+
async loadFrom(resourcePath) {
|
|
4024
|
+
const manifestPath = join(resourcePath, "manifest.json");
|
|
4025
|
+
const manifestContent = await readFile(manifestPath, "utf-8");
|
|
4026
|
+
const manifestData = JSON.parse(manifestContent);
|
|
4027
|
+
const manifest = createRXM2(manifestData);
|
|
4028
|
+
const contentPath = join(resourcePath, "content.tar.gz");
|
|
4029
|
+
const data = await readFile(contentPath);
|
|
4030
|
+
return this.typeHandler.deserialize(data, manifest);
|
|
4031
|
+
}
|
|
4032
|
+
async pull(_locator, _options) {
|
|
4033
|
+
throw new RegistryError("Pull not implemented yet - see issue #018");
|
|
4034
|
+
}
|
|
4035
|
+
async publish(_resource, _options) {
|
|
4036
|
+
throw new RegistryError("Publish not implemented yet - see issue #018");
|
|
3990
4037
|
}
|
|
3991
4038
|
async link(resource) {
|
|
3992
4039
|
const locator = resource.manifest.toLocator();
|
|
3993
|
-
const resourcePath = this.buildPath(locator);
|
|
4040
|
+
const resourcePath = this.buildPath(locator, "local");
|
|
3994
4041
|
await mkdir(resourcePath, { recursive: true });
|
|
3995
4042
|
const manifestPath = join(resourcePath, "manifest.json");
|
|
3996
4043
|
await writeFile(manifestPath, JSON.stringify(resource.manifest.toJSON(), null, 2), "utf-8");
|
|
@@ -3999,58 +4046,62 @@ class LocalRegistry {
|
|
|
3999
4046
|
await writeFile(contentPath, serialized);
|
|
4000
4047
|
}
|
|
4001
4048
|
async get(locator) {
|
|
4002
|
-
|
|
4049
|
+
const area = await this.findArea(locator);
|
|
4050
|
+
if (!area) {
|
|
4003
4051
|
throw new RegistryError(`Resource not found: ${locator}`);
|
|
4004
4052
|
}
|
|
4005
|
-
const resourcePath = this.buildPath(locator);
|
|
4006
|
-
|
|
4007
|
-
const manifestContent = await readFile(manifestPath, "utf-8");
|
|
4008
|
-
const manifestData = JSON.parse(manifestContent);
|
|
4009
|
-
const manifest = createRXM2(manifestData);
|
|
4010
|
-
const contentPath = join(resourcePath, "content.tar.gz");
|
|
4011
|
-
const data = await readFile(contentPath);
|
|
4012
|
-
return this.typeHandler.deserialize(data, manifest);
|
|
4053
|
+
const resourcePath = this.buildPath(locator, area);
|
|
4054
|
+
return this.loadFrom(resourcePath);
|
|
4013
4055
|
}
|
|
4014
4056
|
async resolve(locator) {
|
|
4015
4057
|
const rxr = await this.get(locator);
|
|
4016
4058
|
return this.typeHandler.resolve(rxr);
|
|
4017
4059
|
}
|
|
4018
4060
|
async exists(locator) {
|
|
4019
|
-
const
|
|
4020
|
-
|
|
4021
|
-
try {
|
|
4022
|
-
await stat(manifestPath);
|
|
4023
|
-
return true;
|
|
4024
|
-
} catch {
|
|
4025
|
-
return false;
|
|
4026
|
-
}
|
|
4061
|
+
const area = await this.findArea(locator);
|
|
4062
|
+
return area !== null;
|
|
4027
4063
|
}
|
|
4028
4064
|
async delete(locator) {
|
|
4029
|
-
|
|
4030
|
-
|
|
4065
|
+
const isLocal = this.isLocalOnlyLocator(locator);
|
|
4066
|
+
if (isLocal) {
|
|
4067
|
+
const localPath = this.buildPath(locator, "local");
|
|
4068
|
+
if (await this.existsAt(localPath)) {
|
|
4069
|
+
await rm(localPath, { recursive: true, force: true });
|
|
4070
|
+
}
|
|
4071
|
+
} else {
|
|
4072
|
+
const cachePath = this.buildPath(locator, "cache");
|
|
4073
|
+
if (await this.existsAt(cachePath)) {
|
|
4074
|
+
await rm(cachePath, { recursive: true, force: true });
|
|
4075
|
+
}
|
|
4031
4076
|
}
|
|
4032
|
-
const resourcePath = this.buildPath(locator);
|
|
4033
|
-
await rm(resourcePath, { recursive: true, force: true });
|
|
4034
4077
|
}
|
|
4035
4078
|
async search(options) {
|
|
4036
4079
|
const { query, limit, offset = 0 } = options ?? {};
|
|
4037
|
-
let entries;
|
|
4038
|
-
try {
|
|
4039
|
-
entries = await this.listRecursive(this.basePath);
|
|
4040
|
-
} catch {
|
|
4041
|
-
return [];
|
|
4042
|
-
}
|
|
4043
4080
|
const locators = [];
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4081
|
+
const localDir = join(this.basePath, "local");
|
|
4082
|
+
try {
|
|
4083
|
+
const localEntries = await this.listRecursive(localDir);
|
|
4084
|
+
for (const entry of localEntries) {
|
|
4085
|
+
if (!entry.endsWith("manifest.json"))
|
|
4086
|
+
continue;
|
|
4087
|
+
const relativePath = entry.slice(localDir.length + 1);
|
|
4088
|
+
const rxl = this.parseLocalEntry(relativePath);
|
|
4089
|
+
if (rxl)
|
|
4090
|
+
locators.push(rxl);
|
|
4047
4091
|
}
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4092
|
+
} catch {}
|
|
4093
|
+
const cacheDir = join(this.basePath, "cache");
|
|
4094
|
+
try {
|
|
4095
|
+
const cacheEntries = await this.listRecursive(cacheDir);
|
|
4096
|
+
for (const entry of cacheEntries) {
|
|
4097
|
+
if (!entry.endsWith("manifest.json"))
|
|
4098
|
+
continue;
|
|
4099
|
+
const relativePath = entry.slice(cacheDir.length + 1);
|
|
4100
|
+
const rxl = this.parseCacheEntry(relativePath);
|
|
4101
|
+
if (rxl)
|
|
4102
|
+
locators.push(rxl);
|
|
4052
4103
|
}
|
|
4053
|
-
}
|
|
4104
|
+
} catch {}
|
|
4054
4105
|
let filtered = locators;
|
|
4055
4106
|
if (query) {
|
|
4056
4107
|
const lowerQuery = query.toLowerCase();
|
|
@@ -4081,7 +4132,27 @@ class LocalRegistry {
|
|
|
4081
4132
|
} catch {}
|
|
4082
4133
|
return results;
|
|
4083
4134
|
}
|
|
4084
|
-
|
|
4135
|
+
parseLocalEntry(entry) {
|
|
4136
|
+
const dirPath = entry.replace(/[/\\]manifest\.json$/, "");
|
|
4137
|
+
const parts = dirPath.split(/[/\\]/);
|
|
4138
|
+
if (parts.length < 2) {
|
|
4139
|
+
return null;
|
|
4140
|
+
}
|
|
4141
|
+
const version = parts.pop();
|
|
4142
|
+
const nameTypePart = parts.shift();
|
|
4143
|
+
const { name, type } = this.parseNameType(nameTypePart);
|
|
4144
|
+
let locatorStr = name;
|
|
4145
|
+
if (type) {
|
|
4146
|
+
locatorStr += `.${type}`;
|
|
4147
|
+
}
|
|
4148
|
+
locatorStr += `@${version}`;
|
|
4149
|
+
try {
|
|
4150
|
+
return parseRXL3(locatorStr);
|
|
4151
|
+
} catch {
|
|
4152
|
+
return null;
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
4155
|
+
parseCacheEntry(entry) {
|
|
4085
4156
|
const dirPath = entry.replace(/[/\\]manifest\.json$/, "");
|
|
4086
4157
|
const parts = dirPath.split(/[/\\]/);
|
|
4087
4158
|
if (parts.length < 3) {
|
|
@@ -4091,16 +4162,7 @@ class LocalRegistry {
|
|
|
4091
4162
|
const nameTypePart = parts.pop();
|
|
4092
4163
|
const domain = parts.shift();
|
|
4093
4164
|
const path = parts.length > 0 ? parts.join("/") : undefined;
|
|
4094
|
-
const
|
|
4095
|
-
let name;
|
|
4096
|
-
let type;
|
|
4097
|
-
if (dotIndex !== -1) {
|
|
4098
|
-
name = nameTypePart.substring(0, dotIndex);
|
|
4099
|
-
type = nameTypePart.substring(dotIndex + 1);
|
|
4100
|
-
} else {
|
|
4101
|
-
name = nameTypePart;
|
|
4102
|
-
type = undefined;
|
|
4103
|
-
}
|
|
4165
|
+
const { name, type } = this.parseNameType(nameTypePart);
|
|
4104
4166
|
let locatorStr = domain;
|
|
4105
4167
|
if (path) {
|
|
4106
4168
|
locatorStr += `/${path}`;
|
|
@@ -4116,6 +4178,17 @@ class LocalRegistry {
|
|
|
4116
4178
|
return null;
|
|
4117
4179
|
}
|
|
4118
4180
|
}
|
|
4181
|
+
parseNameType(nameTypePart) {
|
|
4182
|
+
const dotIndex = nameTypePart.lastIndexOf(".");
|
|
4183
|
+
if (dotIndex !== -1) {
|
|
4184
|
+
return {
|
|
4185
|
+
name: nameTypePart.substring(0, dotIndex),
|
|
4186
|
+
type: nameTypePart.substring(dotIndex + 1)
|
|
4187
|
+
};
|
|
4188
|
+
} else {
|
|
4189
|
+
return { name: nameTypePart, type: undefined };
|
|
4190
|
+
}
|
|
4191
|
+
}
|
|
4119
4192
|
}
|
|
4120
4193
|
|
|
4121
4194
|
class RemoteRegistry {
|
|
@@ -4128,7 +4201,10 @@ class RemoteRegistry {
|
|
|
4128
4201
|
supportType(type) {
|
|
4129
4202
|
this.typeHandler.register(type);
|
|
4130
4203
|
}
|
|
4131
|
-
async
|
|
4204
|
+
async pull(_locator, _options) {
|
|
4205
|
+
throw new RegistryError("Cannot pull to remote registry - use local registry for pulling");
|
|
4206
|
+
}
|
|
4207
|
+
async publish(_resource, _options) {
|
|
4132
4208
|
throw new RegistryError("Remote registry publish not implemented yet");
|
|
4133
4209
|
}
|
|
4134
4210
|
async link(_resource) {
|
|
@@ -4186,15 +4262,215 @@ class RemoteRegistry {
|
|
|
4186
4262
|
return (data.results || []).map((locator) => parseRXL3(locator));
|
|
4187
4263
|
}
|
|
4188
4264
|
}
|
|
4265
|
+
var DEFAULT_GIT_CACHE = `${homedir2()}/.resourcex/.git-cache`;
|
|
4266
|
+
|
|
4267
|
+
class GitRegistry {
|
|
4268
|
+
url;
|
|
4269
|
+
ref;
|
|
4270
|
+
basePath;
|
|
4271
|
+
cacheDir;
|
|
4272
|
+
typeHandler;
|
|
4273
|
+
trustedDomain;
|
|
4274
|
+
constructor(config) {
|
|
4275
|
+
this.url = config.url;
|
|
4276
|
+
this.ref = config.ref ?? "main";
|
|
4277
|
+
this.basePath = config.basePath ?? ".resourcex";
|
|
4278
|
+
this.typeHandler = TypeHandlerChain2.create();
|
|
4279
|
+
this.trustedDomain = config.domain;
|
|
4280
|
+
if (this.isRemoteUrl(config.url) && !config.domain) {
|
|
4281
|
+
throw new RegistryError(`Remote git registry requires a trusted domain.
|
|
4282
|
+
|
|
4283
|
+
` + `Either:
|
|
4284
|
+
` + `1. Use discoverRegistry("your-domain.com") to auto-bind domain
|
|
4285
|
+
` + `2. Explicitly set domain: createRegistry({ type: "git", url: "...", domain: "your-domain.com" })
|
|
4286
|
+
|
|
4287
|
+
` + `This ensures resources from untrusted sources cannot impersonate your domain.`);
|
|
4288
|
+
}
|
|
4289
|
+
this.cacheDir = this.buildCacheDir(config.url);
|
|
4290
|
+
}
|
|
4291
|
+
isRemoteUrl(url) {
|
|
4292
|
+
return url.startsWith("git@") || url.startsWith("https://") || url.startsWith("http://");
|
|
4293
|
+
}
|
|
4294
|
+
buildCacheDir(url) {
|
|
4295
|
+
let normalized = url;
|
|
4296
|
+
if (url.startsWith("git@")) {
|
|
4297
|
+
normalized = url.slice(4).replace(":", "/");
|
|
4298
|
+
}
|
|
4299
|
+
if (normalized.endsWith(".git")) {
|
|
4300
|
+
normalized = normalized.slice(0, -4);
|
|
4301
|
+
}
|
|
4302
|
+
const dirName = normalized.replace(/\//g, "-");
|
|
4303
|
+
return join2(DEFAULT_GIT_CACHE, dirName);
|
|
4304
|
+
}
|
|
4305
|
+
supportType(type) {
|
|
4306
|
+
this.typeHandler.register(type);
|
|
4307
|
+
}
|
|
4308
|
+
async ensureCloned() {
|
|
4309
|
+
const gitDir = join2(this.cacheDir, ".git");
|
|
4310
|
+
try {
|
|
4311
|
+
await stat2(gitDir);
|
|
4312
|
+
this.gitExec(`fetch origin ${this.ref}`);
|
|
4313
|
+
this.gitExec(`checkout FETCH_HEAD`);
|
|
4314
|
+
} catch {
|
|
4315
|
+
await mkdir2(DEFAULT_GIT_CACHE, { recursive: true });
|
|
4316
|
+
execSync(`git clone --depth 1 --branch ${this.ref} ${this.url} ${this.cacheDir}`, {
|
|
4317
|
+
stdio: "pipe"
|
|
4318
|
+
});
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
gitExec(command) {
|
|
4322
|
+
execSync(`git -C ${this.cacheDir} ${command}`, { stdio: "pipe" });
|
|
4323
|
+
}
|
|
4324
|
+
buildResourcePath(locator) {
|
|
4325
|
+
const rxl = parseRXL3(locator);
|
|
4326
|
+
const domain = rxl.domain ?? "localhost";
|
|
4327
|
+
const version = rxl.version ?? "latest";
|
|
4328
|
+
let path = join2(this.cacheDir, this.basePath, domain);
|
|
4329
|
+
if (rxl.path) {
|
|
4330
|
+
path = join2(path, rxl.path);
|
|
4331
|
+
}
|
|
4332
|
+
const resourceName = rxl.type ? `${rxl.name}.${rxl.type}` : rxl.name;
|
|
4333
|
+
return join2(path, resourceName, version);
|
|
4334
|
+
}
|
|
4335
|
+
async get(locator) {
|
|
4336
|
+
await this.ensureCloned();
|
|
4337
|
+
const resourcePath = this.buildResourcePath(locator);
|
|
4338
|
+
const manifestPath = join2(resourcePath, "manifest.json");
|
|
4339
|
+
try {
|
|
4340
|
+
await stat2(manifestPath);
|
|
4341
|
+
} catch {
|
|
4342
|
+
throw new RegistryError(`Resource not found: ${locator}`);
|
|
4343
|
+
}
|
|
4344
|
+
const manifestContent = await readFile2(manifestPath, "utf-8");
|
|
4345
|
+
const manifestData = JSON.parse(manifestContent);
|
|
4346
|
+
const manifest = createRXM2(manifestData);
|
|
4347
|
+
if (this.trustedDomain && manifest.domain !== this.trustedDomain) {
|
|
4348
|
+
throw new RegistryError(`Untrusted domain: resource claims "${manifest.domain}" but registry only trusts "${this.trustedDomain}"`);
|
|
4349
|
+
}
|
|
4350
|
+
const contentPath = join2(resourcePath, "content.tar.gz");
|
|
4351
|
+
const data = await readFile2(contentPath);
|
|
4352
|
+
return this.typeHandler.deserialize(data, manifest);
|
|
4353
|
+
}
|
|
4354
|
+
async resolve(locator) {
|
|
4355
|
+
const rxr = await this.get(locator);
|
|
4356
|
+
return this.typeHandler.resolve(rxr);
|
|
4357
|
+
}
|
|
4358
|
+
async exists(locator) {
|
|
4359
|
+
try {
|
|
4360
|
+
await this.ensureCloned();
|
|
4361
|
+
const resourcePath = this.buildResourcePath(locator);
|
|
4362
|
+
const manifestPath = join2(resourcePath, "manifest.json");
|
|
4363
|
+
await stat2(manifestPath);
|
|
4364
|
+
return true;
|
|
4365
|
+
} catch {
|
|
4366
|
+
return false;
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
async search(options) {
|
|
4370
|
+
await this.ensureCloned();
|
|
4371
|
+
const { query, limit, offset = 0 } = options ?? {};
|
|
4372
|
+
const locators = [];
|
|
4373
|
+
const baseDir = join2(this.cacheDir, this.basePath);
|
|
4374
|
+
try {
|
|
4375
|
+
const entries = await this.listRecursive(baseDir);
|
|
4376
|
+
for (const entry of entries) {
|
|
4377
|
+
if (!entry.endsWith("manifest.json"))
|
|
4378
|
+
continue;
|
|
4379
|
+
const relativePath = entry.slice(baseDir.length + 1);
|
|
4380
|
+
const rxl = this.parseEntryToRXL(relativePath);
|
|
4381
|
+
if (rxl)
|
|
4382
|
+
locators.push(rxl);
|
|
4383
|
+
}
|
|
4384
|
+
} catch {
|
|
4385
|
+
return [];
|
|
4386
|
+
}
|
|
4387
|
+
let filtered = locators;
|
|
4388
|
+
if (query) {
|
|
4389
|
+
const lowerQuery = query.toLowerCase();
|
|
4390
|
+
filtered = locators.filter((rxl) => {
|
|
4391
|
+
const searchText = `${rxl.domain ?? ""} ${rxl.path ?? ""} ${rxl.name} ${rxl.type ?? ""}`.toLowerCase();
|
|
4392
|
+
return searchText.includes(lowerQuery);
|
|
4393
|
+
});
|
|
4394
|
+
}
|
|
4395
|
+
let result = filtered.slice(offset);
|
|
4396
|
+
if (limit !== undefined) {
|
|
4397
|
+
result = result.slice(0, limit);
|
|
4398
|
+
}
|
|
4399
|
+
return result;
|
|
4400
|
+
}
|
|
4401
|
+
async listRecursive(dir) {
|
|
4402
|
+
const results = [];
|
|
4403
|
+
try {
|
|
4404
|
+
const entries = await readdir2(dir, { withFileTypes: true });
|
|
4405
|
+
for (const entry of entries) {
|
|
4406
|
+
const fullPath = join2(dir, entry.name);
|
|
4407
|
+
if (entry.isDirectory()) {
|
|
4408
|
+
const subEntries = await this.listRecursive(fullPath);
|
|
4409
|
+
results.push(...subEntries);
|
|
4410
|
+
} else {
|
|
4411
|
+
results.push(fullPath);
|
|
4412
|
+
}
|
|
4413
|
+
}
|
|
4414
|
+
} catch {}
|
|
4415
|
+
return results;
|
|
4416
|
+
}
|
|
4417
|
+
parseEntryToRXL(entry) {
|
|
4418
|
+
const dirPath = entry.replace(/[/\\]manifest\.json$/, "");
|
|
4419
|
+
const parts = dirPath.split(/[/\\]/);
|
|
4420
|
+
if (parts.length < 3)
|
|
4421
|
+
return null;
|
|
4422
|
+
const version = parts.pop();
|
|
4423
|
+
const nameTypePart = parts.pop();
|
|
4424
|
+
const domain = parts.shift();
|
|
4425
|
+
const path = parts.length > 0 ? parts.join("/") : undefined;
|
|
4426
|
+
const dotIndex = nameTypePart.lastIndexOf(".");
|
|
4427
|
+
let name;
|
|
4428
|
+
let type;
|
|
4429
|
+
if (dotIndex !== -1) {
|
|
4430
|
+
name = nameTypePart.substring(0, dotIndex);
|
|
4431
|
+
type = nameTypePart.substring(dotIndex + 1);
|
|
4432
|
+
} else {
|
|
4433
|
+
name = nameTypePart;
|
|
4434
|
+
type = undefined;
|
|
4435
|
+
}
|
|
4436
|
+
let locatorStr = domain;
|
|
4437
|
+
if (path)
|
|
4438
|
+
locatorStr += `/${path}`;
|
|
4439
|
+
locatorStr += `/${name}`;
|
|
4440
|
+
if (type)
|
|
4441
|
+
locatorStr += `.${type}`;
|
|
4442
|
+
locatorStr += `@${version}`;
|
|
4443
|
+
try {
|
|
4444
|
+
return parseRXL3(locatorStr);
|
|
4445
|
+
} catch {
|
|
4446
|
+
return null;
|
|
4447
|
+
}
|
|
4448
|
+
}
|
|
4449
|
+
async pull(_locator, _options) {
|
|
4450
|
+
throw new RegistryError("GitRegistry is read-only - use LocalRegistry.pull()");
|
|
4451
|
+
}
|
|
4452
|
+
async publish(_resource, _options) {
|
|
4453
|
+
throw new RegistryError("GitRegistry is read-only - use LocalRegistry.publish()");
|
|
4454
|
+
}
|
|
4455
|
+
async link(_resource) {
|
|
4456
|
+
throw new RegistryError("GitRegistry is read-only - use LocalRegistry.link()");
|
|
4457
|
+
}
|
|
4458
|
+
async delete(_locator) {
|
|
4459
|
+
throw new RegistryError("GitRegistry is read-only - use LocalRegistry.delete()");
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4189
4462
|
function createRegistry(config) {
|
|
4190
4463
|
if (isRemoteConfig(config)) {
|
|
4191
4464
|
return new RemoteRegistry(config);
|
|
4192
4465
|
}
|
|
4466
|
+
if (isGitConfig(config)) {
|
|
4467
|
+
return new GitRegistry(config);
|
|
4468
|
+
}
|
|
4193
4469
|
return new LocalRegistry(config);
|
|
4194
4470
|
}
|
|
4195
4471
|
// ../loader/dist/index.js
|
|
4196
|
-
import { join as
|
|
4197
|
-
import { stat as
|
|
4472
|
+
import { join as join3, relative } from "node:path";
|
|
4473
|
+
import { stat as stat3, readFile as readFile3, readdir as readdir3 } from "node:fs/promises";
|
|
4198
4474
|
import { gzip as gzip4, gunzip as gunzip4 } from "node:zlib";
|
|
4199
4475
|
import { promisify as promisify4 } from "node:util";
|
|
4200
4476
|
|
|
@@ -5386,22 +5662,22 @@ async function createRXC4(input) {
|
|
|
5386
5662
|
class FolderLoader {
|
|
5387
5663
|
async canLoad(source) {
|
|
5388
5664
|
try {
|
|
5389
|
-
const stats = await
|
|
5665
|
+
const stats = await stat3(source);
|
|
5390
5666
|
if (!stats.isDirectory()) {
|
|
5391
5667
|
return false;
|
|
5392
5668
|
}
|
|
5393
|
-
const manifestPath =
|
|
5394
|
-
const manifestStats = await
|
|
5669
|
+
const manifestPath = join3(source, "resource.json");
|
|
5670
|
+
const manifestStats = await stat3(manifestPath);
|
|
5395
5671
|
return manifestStats.isFile();
|
|
5396
5672
|
} catch {
|
|
5397
5673
|
return false;
|
|
5398
5674
|
}
|
|
5399
5675
|
}
|
|
5400
5676
|
async load(folderPath) {
|
|
5401
|
-
const manifestPath =
|
|
5677
|
+
const manifestPath = join3(folderPath, "resource.json");
|
|
5402
5678
|
let manifestJson;
|
|
5403
5679
|
try {
|
|
5404
|
-
manifestJson = await
|
|
5680
|
+
manifestJson = await readFile3(manifestPath, "utf-8");
|
|
5405
5681
|
} catch (error) {
|
|
5406
5682
|
throw new ResourceXError4(`Failed to read resource.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
5407
5683
|
}
|
|
@@ -5441,15 +5717,15 @@ class FolderLoader {
|
|
|
5441
5717
|
}
|
|
5442
5718
|
async readFolderFiles(folderPath, basePath = folderPath) {
|
|
5443
5719
|
const files = {};
|
|
5444
|
-
const entries = await
|
|
5720
|
+
const entries = await readdir3(folderPath, { withFileTypes: true });
|
|
5445
5721
|
for (const entry of entries) {
|
|
5446
|
-
const fullPath =
|
|
5722
|
+
const fullPath = join3(folderPath, entry.name);
|
|
5447
5723
|
const relativePath = relative(basePath, fullPath);
|
|
5448
5724
|
if (relativePath === "resource.json") {
|
|
5449
5725
|
continue;
|
|
5450
5726
|
}
|
|
5451
5727
|
if (entry.isFile()) {
|
|
5452
|
-
files[relativePath] = await
|
|
5728
|
+
files[relativePath] = await readFile3(fullPath);
|
|
5453
5729
|
} else if (entry.isDirectory()) {
|
|
5454
5730
|
const subFiles = await this.readFolderFiles(fullPath, basePath);
|
|
5455
5731
|
Object.assign(files, subFiles);
|
|
@@ -5468,7 +5744,7 @@ async function loadResource(source, config) {
|
|
|
5468
5744
|
}
|
|
5469
5745
|
|
|
5470
5746
|
// src/index.ts
|
|
5471
|
-
var VERSION = "
|
|
5747
|
+
var VERSION = "2.0.0";
|
|
5472
5748
|
export {
|
|
5473
5749
|
textType,
|
|
5474
5750
|
parseRXL,
|
|
@@ -5491,4 +5767,4 @@ export {
|
|
|
5491
5767
|
ContentError
|
|
5492
5768
|
};
|
|
5493
5769
|
|
|
5494
|
-
//# debugId=
|
|
5770
|
+
//# debugId=3C36FF6A5291529664756E2164756E21
|