feat: add branch support, sync resolution, and dynamic cache TTL
- Add branch detection in parseRemoteIOR for GitHub and Gitea - Support fetching from branches in addition to tags - Implement synchronous remote resolution using sync-fetch - Add dynamic cache TTL based on version type (beta/rc/branch/stable) - Export sync functions for Metro bundler usage - Fix remote component resolution in Metro (no more sync errors)
This commit is contained in:
103
lib/ior-core.js
103
lib/ior-core.js
@@ -31,14 +31,23 @@ function parseRemoteIOR(ior) {
|
||||
// ior:github:owner/repo:componentname@version
|
||||
const [, , repoPath, componentAndVersion] = parts;
|
||||
const [owner, repo] = repoPath.split('/');
|
||||
const [componentName, version] = componentAndVersion.split('@');
|
||||
|
||||
const [componentName, versionOrBranch] = componentAndVersion.split('@');
|
||||
|
||||
// Detect if it's a branch
|
||||
const isBranch = versionOrBranch && (
|
||||
versionOrBranch.includes('/') ||
|
||||
versionOrBranch.startsWith('main') ||
|
||||
versionOrBranch.startsWith('master') ||
|
||||
versionOrBranch.startsWith('dev')
|
||||
);
|
||||
|
||||
return {
|
||||
type: 'github',
|
||||
owner,
|
||||
repository: repo,
|
||||
componentName,
|
||||
version,
|
||||
version: !isBranch ? versionOrBranch : undefined,
|
||||
branch: isBranch ? versionOrBranch : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -46,24 +55,33 @@ function parseRemoteIOR(ior) {
|
||||
// Two possible formats:
|
||||
// ior:gitea:instance.com:owner/repo:componentname@version (5 parts)
|
||||
// ior:gitea:instance.com:owner/repo/componentname@version (4 parts - component name in path)
|
||||
|
||||
|
||||
if (parts.length === 4) {
|
||||
// Format: ior:gitea:instance.com:owner/repo/componentname@version
|
||||
const [, , instance, pathAndVersion] = parts;
|
||||
const [fullPath, version] = pathAndVersion.split('@');
|
||||
const [fullPath, versionOrBranch] = pathAndVersion.split('@');
|
||||
const pathParts = fullPath.split('/');
|
||||
|
||||
|
||||
const owner = pathParts[0];
|
||||
const componentName = pathParts[pathParts.length - 1];
|
||||
const repository = pathParts.slice(1).join('/') || componentName;
|
||||
|
||||
|
||||
// Detect if it's a branch
|
||||
const isBranch = versionOrBranch && (
|
||||
versionOrBranch.includes('/') ||
|
||||
versionOrBranch.startsWith('main') ||
|
||||
versionOrBranch.startsWith('master') ||
|
||||
versionOrBranch.startsWith('dev')
|
||||
);
|
||||
|
||||
return {
|
||||
type: 'gitea',
|
||||
instance,
|
||||
owner,
|
||||
repository,
|
||||
componentName,
|
||||
version,
|
||||
version: !isBranch ? versionOrBranch : undefined,
|
||||
branch: isBranch ? versionOrBranch : undefined,
|
||||
};
|
||||
} else if (parts.length === 5) {
|
||||
// Format: ior:gitea:instance.com:owner/repo:componentname@version
|
||||
@@ -71,18 +89,27 @@ function parseRemoteIOR(ior) {
|
||||
const repoPathParts = repoPath.split('/');
|
||||
const owner = repoPathParts[0];
|
||||
const repository = repoPathParts.slice(1).join('/');
|
||||
const [componentName, version] = componentAndVersion.split('@');
|
||||
|
||||
const [componentName, versionOrBranch] = componentAndVersion.split('@');
|
||||
|
||||
// Detect if it's a branch
|
||||
const isBranch = versionOrBranch && (
|
||||
versionOrBranch.includes('/') ||
|
||||
versionOrBranch.startsWith('main') ||
|
||||
versionOrBranch.startsWith('master') ||
|
||||
versionOrBranch.startsWith('dev')
|
||||
);
|
||||
|
||||
return {
|
||||
type: 'gitea',
|
||||
instance,
|
||||
owner,
|
||||
repository,
|
||||
componentName,
|
||||
version,
|
||||
version: !isBranch ? versionOrBranch : undefined,
|
||||
branch: isBranch ? versionOrBranch : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -199,15 +226,29 @@ async function fetchUrlBuffer(url) {
|
||||
* Fetch component archive from GitHub
|
||||
*/
|
||||
async function fetchFromGitHub(config) {
|
||||
const { owner, repository, componentName, version } = config;
|
||||
|
||||
// Try both tag formats: "1.0.0" and "v1.0.0"
|
||||
const { owner, repository, componentName, version, branch } = config;
|
||||
|
||||
// If it's a branch, fetch from branch
|
||||
if (branch) {
|
||||
const archiveUrl = `https://api.github.com/repos/${owner}/${repository}/tarball/${branch}`;
|
||||
|
||||
try {
|
||||
console.log(`[IOR Resolver] Fetching GitHub branch: ${branch}`);
|
||||
const archiveBuffer = await fetchUrlBuffer(archiveUrl);
|
||||
console.log(`[IOR Resolver] Downloaded archive from GitHub branch ${branch} (${archiveBuffer.length} bytes)`);
|
||||
return { archive: archiveBuffer, componentName };
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to fetch branch ${branch} from GitHub: ${owner}/${repository} - ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, try tag formats: "1.0.0" and "v1.0.0"
|
||||
const tagVariants = [version, `v${version}`];
|
||||
|
||||
|
||||
for (const tag of tagVariants) {
|
||||
// GitHub API endpoint for tarball
|
||||
const archiveUrl = `https://api.github.com/repos/${owner}/${repository}/tarball/${tag}`;
|
||||
|
||||
|
||||
try {
|
||||
console.log(`[IOR Resolver] Fetching GitHub archive: ${archiveUrl}`);
|
||||
const archiveBuffer = await fetchUrlBuffer(archiveUrl);
|
||||
@@ -218,7 +259,7 @@ async function fetchFromGitHub(config) {
|
||||
// Try next tag variant
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
throw new Error(`Failed to fetch component from GitHub: ${owner}/${repository}@${version} (tried tags: ${tagVariants.join(', ')})`);
|
||||
}
|
||||
|
||||
@@ -226,15 +267,29 @@ async function fetchFromGitHub(config) {
|
||||
* Fetch component archive from Gitea
|
||||
*/
|
||||
async function fetchFromGitea(config) {
|
||||
const { instance, owner, repository, componentName, version } = config;
|
||||
|
||||
// Try both tag formats: "1.0.0" and "v1.0.0"
|
||||
const { instance, owner, repository, componentName, version, branch } = config;
|
||||
|
||||
// If it's a branch, fetch from branch
|
||||
if (branch) {
|
||||
const archiveUrl = `https://${instance}/api/v1/repos/${owner}/${repository}/archive/${branch}.tar.gz`;
|
||||
|
||||
try {
|
||||
console.log(`[IOR Resolver] Fetching Gitea branch: ${branch}`);
|
||||
const archiveBuffer = await fetchUrlBuffer(archiveUrl);
|
||||
console.log(`[IOR Resolver] Downloaded archive from Gitea branch ${branch} (${archiveBuffer.length} bytes)`);
|
||||
return { archive: archiveBuffer, componentName };
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to fetch branch ${branch} from Gitea: ${instance}/${owner}/${repository} - ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, try tag formats: "1.0.0" and "v1.0.0"
|
||||
const tagVariants = [version, `v${version}`];
|
||||
|
||||
|
||||
for (const tag of tagVariants) {
|
||||
// Try to download the archive
|
||||
const archiveUrl = `https://${instance}/api/v1/repos/${owner}/${repository}/archive/${tag}.tar.gz`;
|
||||
|
||||
|
||||
try {
|
||||
console.log(`[IOR Resolver] Fetching Gitea archive: ${archiveUrl}`);
|
||||
const archiveBuffer = await fetchUrlBuffer(archiveUrl);
|
||||
@@ -245,7 +300,7 @@ async function fetchFromGitea(config) {
|
||||
// Try next tag variant
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
throw new Error(`Failed to fetch component from Gitea: ${instance}/${owner}/${repository}@${version} (tried tags: ${tagVariants.join(', ')})`);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user