Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export function trySpecs(specBase: string, adaptVersion: SemVer): SpecInfo[] {
const specs: SpecInfo[] = [];
let pkgInfo: pkgArg.Result | undefined;
let type: SpecInfo["type"] | undefined;
if (isLocalSpec(specBase)) type = "local";
try {
pkgInfo = pkgArg(specBase);
} catch (err) { /* */ }
if (type !== "local") {
const versions = tryVersions(adaptVersion);
if (mightBeGallerySpec(specBase)) {
const base = galleryUrl(specBase);
[ ...versions, undefined ].forEach((v) => specs.push({
base,
complete: galleryUrl(specBase, v),
type: "git",
}));
}
if (pkgInfo) {
type = toSpecInfoType(pkgInfo.type);
const configBuffer = await fse.readFile(configPath);
const appJson = configName === 'app.json' ? JSON.parse(configBuffer.toString()) : {};
/**
* Perform validations
*/
if (!exp.sdkVersion) throw new Error(`Couldn't read ${configName}`);
if (!Versions.gteSdkVersion(exp, '34.0.0')) {
throw new Error(`Ejecting to a bare project is only available for SDK 34 and higher`);
}
// Validate that the template exists
let sdkMajorVersionNumber = semver.major(exp.sdkVersion);
let templateSpec = npmPackageArg(`expo-template-bare-minimum@sdk-${sdkMajorVersionNumber}`);
try {
await pacote.manifest(templateSpec);
} catch (e) {
if (e.code === 'E404') {
throw new Error(
`Unable to eject because an eject template for SDK ${sdkMajorVersionNumber} was not found`
);
} else {
throw e;
}
}
/**
* Customize app.json
*/
let { displayName, name } = await getAppNamesAsync(projectRoot);
filterLocalDeps(name, deps) {
// Change the working directory since npm-package-arg uses it when calling
// path.resolve
let originalCwd = process.cwd();
let packagePath = path.resolve(this.root, name);
process.chdir(packagePath);
let localDeps = {};
try {
for (let [dep, version] of toPairsIn(deps)) {
let descriptor = npmPackageArg(`${dep}@${version}`);
if (descriptor.type === 'local') {
localDeps[dep] = descriptor.spec;
}
}
} finally {
process.chdir(originalCwd);
}
return localDeps;
}
let validationResult = validateName(parentDir, dirName);
if (validationResult !== true) {
throw new CommandError('INVALID_PROJECT_DIR', validationResult);
}
} else if (options.parent && options.parent.nonInteractive) {
throw new CommandError(
'NON_INTERACTIVE',
'The project dir argument is required in non-interactive mode.'
);
} else {
parentDir = process.cwd();
}
let templateSpec;
if (options.template) {
templateSpec = npmPackageArg(options.template);
// For backwards compatibility, 'blank' and 'tabs' are aliases for
// 'expo-template-blank' and 'expo-template-tabs', respectively.
if (
(templateSpec.name === 'blank' ||
templateSpec.name === 'tabs' ||
templateSpec.name === 'bare-minimum' ||
templateSpec.name === 'bare-foundation') &&
templateSpec.registry
) {
templateSpec.escapedName = `expo-template-${templateSpec.name}`;
templateSpec.name = templateSpec.escapedName;
templateSpec.raw = templateSpec.escapedName;
}
} else {
let descriptionColumn =
const versionedPackages = packages.map(arg => {
const spec = npmPackageArg(arg);
const { name } = spec;
if (['tag', 'version', 'range'].includes(spec.type) && name && bundledNativeModules[name]) {
// Unimodule packages from npm registry are modified to use the bundled version.
const version = bundledNativeModules[name];
const modifiedSpec = `${name}@${version}`;
nativeModules.push(modifiedSpec);
return modifiedSpec;
} else {
// Other packages are passed through unmodified.
others.push(spec.raw);
return spec.raw;
}
});
const messages = [];
export async function getBuilder(
builderPkg: string,
yarnDir: string,
output: Output,
builderDir?: string
): Promise {
let builderWithPkg: BuilderWithPackage = localBuilders[builderPkg];
if (!builderWithPkg) {
if (!builderDir) {
builderDir = await builderDirPromise;
}
const parsed = npa(builderPkg);
const buildersPkg = await readJSON(join(builderDir, 'package.json'));
const pkgName = getPackageName(parsed, buildersPkg) || builderPkg;
const dest = join(builderDir, 'node_modules', pkgName);
try {
const mod = require(dest);
const pkg = require(join(dest, 'package.json'));
builderWithPkg = {
builder: Object.freeze(mod),
package: Object.freeze(pkg),
};
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
output.debug(
`Attempted to require ${builderPkg}, but it is not installed`
);
const pkgSet = new Set([builderPkg]);
function resolveBareModule(spec: string, pathname?: string) {
const npmSpec = resolveNpmSpec(spec);
switch (npmSpec.type) {
case 'range':
case 'version': {
return unpkgCdn.resolveBareModule(spec, pathname);
}
case 'git': {
if (npmSpec.hosted && npmSpec.hosted.type === 'github') {
const resolvedSpec = `${npmSpec.hosted.user}/${npmSpec.hosted.project}@${npmSpec.gitRange ||
npmSpec.gitCommittish}`;
return githubCdn.resolveBareModule(resolvedSpec, pathname);
}
throw new NotSupportedError(
`Unable to resolve '${spec}' because dependencies of type '${npmSpec.type}' are not yet supported`
);
};
}
}),
},
{
nonInteractiveHelp:
'--template: argument is required in non-interactive mode. Valid choices are: ' +
FEATURED_TEMPLATES.map(template =>
typeof template === 'object' && template.shortName ? `'${template.shortName}'` : ''
)
.filter(text => text)
.join(', ') +
' or any custom template (name of npm package).',
}
);
templateSpec = npmPackageArg(template);
}
if (options.workflow) {
log.warn(
`The --workflow flag is deprecated. Workflow is chosen automatically based on the chosen template.`
);
}
let initialConfig;
let templateManifest = await pacote.manifest(templateSpec);
let isBare = BARE_WORKFLOW_TEMPLATES.includes(templateManifest.name);
if (isBare) {
initialConfig = await promptForBareConfig(parentDir, dirName, options);
} else {
initialConfig = await promptForManagedConfig(parentDir, dirName, options);
}
.map(name => npmPackageArg(name))
.forEach(spec => {
function getNpmVersion(use = ''): string {
const parsed = npa(use);
if (registryTypes.has(parsed.type)) {
return parsed.fetchSpec || '';
}
return '';
}