Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/bootstrap.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -182,6 +182,7 @@ injector.requireCommand("run|ios", "./commands/run");
injector.requireCommand("run|android", "./commands/run");
injector.requireCommand("run|vision", "./commands/run");
injector.requireCommand("run|visionos", "./commands/run");
injector.requireCommand("run|macos", "./commands/run");
injector.requireCommand("typings", "./commands/typings");

injector.requireCommand("preview", "./commands/preview");
Expand All@@ -197,6 +198,7 @@ injector.requireCommand("build|ios", "./commands/build");
injector.requireCommand("build|android", "./commands/build");
injector.requireCommand("build|vision", "./commands/build");
injector.requireCommand("build|visionos", "./commands/build");
injector.requireCommand("build|macos", "./commands/build");
injector.requireCommand("deploy", "./commands/deploy");

injector.requireCommand("embed", "./commands/embedding/embed");
Expand Down
55 changes: 55 additions & 0 deletions lib/commands/build.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -277,3 +277,58 @@ export class BuildVisionOsCommand extends BuildIosCommand implements ICommand {

injector.registerCommand("build|vision", BuildVisionOsCommand);
injector.registerCommand("build|visionos", BuildVisionOsCommand);

export class BuildMacOSCommand extends BuildIosCommand implements ICommand {
constructor(
protected $options: IOptions,
$errors: IErrors,
$projectData: IProjectData,
$platformsDataService: IPlatformsDataService,
$devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
$buildController: IBuildController,
$platformValidationService: IPlatformValidationService,
$logger: ILogger,
$buildDataService: IBuildDataService,
protected $migrateController: IMigrateController,
) {
super(
$options,
$errors,
$projectData,
$platformsDataService,
$devicePlatformsConstants,
$buildController,
$platformValidationService,
$logger,
$buildDataService,
$migrateController,
);
}

public async execute(args: string[]): Promise<void> {
await this.executeCore([
this.$devicePlatformsConstants.macOS.toLowerCase(),
]);
}

public async canExecute(args: string[]): Promise<boolean> {
const platform = this.$devicePlatformsConstants.macOS;
if (!this.$options.force) {
await this.$migrateController.validate({
projectDir: this.$projectData.projectDir,
platforms: [platform],
});
}

super.validatePlatform(platform);

let canExecute = await super.canExecuteCommandBase(platform);
if (canExecute) {
canExecute = await super.validateArgs(args, platform);
}

return canExecute;
}
}

injector.registerCommand("build|macos", BuildMacOSCommand);
69 changes: 68 additions & 1 deletion lib/commands/run.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,9 +13,14 @@ import {
ANDROID_APP_BUNDLE_SIGNING_ERROR_MESSAGE,
ANDROID_RELEASE_BUILD_ERROR_MESSAGE,
} from "../constants";
import { IOptions, IPlatformValidationService } from "../declarations";
import {
IOpener,
IOptions,
IPlatformValidationService,
} from "../declarations";
import { IMigrateController } from "../definitions/migrate";
import { IProjectData, IProjectDataService } from "../definitions/project";
import { IBuildController, IBuildDataService } from "../definitions/build";

export class RunCommandBase implements ICommand {
private liveSyncCommandHelperAdditionalOptions: ILiveSyncCommandHelperAdditionalOptions =
Expand DownExpand Up@@ -223,3 +228,65 @@ export class RunVisionOSCommand extends RunIosCommand {

injector.registerCommand("run|vision", RunVisionOSCommand);
injector.registerCommand("run|visionos", RunVisionOSCommand);

export class RunMacOSCommand implements ICommand {
public allowedParameters: ICommandParameter[] = [];

public get platform(): string {
return this.$devicePlatformsConstants.macOS || "macOS";
}

constructor(
private $buildController: IBuildController,
private $buildDataService: IBuildDataService,
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
private $errors: IErrors,
private $migrateController: IMigrateController,
private $opener: IOpener,
private $options: IOptions,
private $platformValidationService: IPlatformValidationService,
private $projectDataService: IProjectDataService,
) {}

public async execute(args: string[]): Promise<void> {
const projectData = this.$projectDataService.getProjectData();
const buildData = this.$buildDataService.getBuildData(
projectData.projectDir,
this.platform.toLowerCase(),
this.$options,
);
const outputPath = await this.$buildController.prepareAndBuild(buildData);
await this.$opener.open(outputPath, projectData.projectName);
}

public async canExecute(args: string[]): Promise<boolean> {
const projectData = this.$projectDataService.getProjectData();

if (
!this.$platformValidationService.isPlatformSupportedForOS(
this.platform,
projectData,
)
) {
this.$errors.fail(
`Applications for platform ${this.platform} can not be built on this OS`,
);
}

if (!this.$options.force) {
await this.$migrateController.validate({
projectDir: projectData.projectDir,
platforms: [this.platform],
});
}

return this.$platformValidationService.validateOptions(
this.$options.provision,
this.$options.teamId,
projectData,
this.platform.toLowerCase(),
);
}
}

injector.registerCommand("run|macos", RunMacOSCommand);
3 changes: 3 additions & 0 deletions lib/common/definitions/mobile.d.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -1197,6 +1197,7 @@ declare global {
isAndroidPlatform(platform: string): boolean;
isiOSPlatform(platform: string): boolean;
isvisionOSPlatform(platform: string): boolean;
ismacOSPlatform?(platform: string): boolean;
isApplePlatform(platform: string): boolean;
normalizePlatformName(platform: string): string;
validatePlatformName(platform: string): string;
Expand DownExpand Up@@ -1241,10 +1242,12 @@ declare global {
iOS: string;
Android: string;
visionOS: string;
macOS?: string;

isiOS(value: string): boolean;
isAndroid(value: string): boolean;
isvisionOS(value: string): boolean;
ismacOS?(value: string): boolean;
}

interface IDeviceApplication {
Expand Down
5 changes: 5 additions & 0 deletions lib/common/mobile/device-platforms-constants.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ export class DevicePlatformsConstants
public iOS = "iOS";
public Android = "Android";
public visionOS = "visionOS";
public macOS = "macOS";

public isiOS(value: string) {
return value.toLowerCase() === this.iOS.toLowerCase();
Expand All@@ -18,5 +19,9 @@ export class DevicePlatformsConstants
public isvisionOS(value: string) {
return value.toLowerCase() === this.visionOS.toLowerCase();
}

public ismacOS(value: string) {
return value.toLowerCase() === this.macOS.toLowerCase();
}
}
injector.register("devicePlatformsConstants", DevicePlatformsConstants);
17 changes: 16 additions & 1 deletion lib/common/mobile/mobile-helper.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,6 +21,7 @@ export class MobileHelper implements Mobile.IMobileHelper {
this.$devicePlatformsConstants.iOS,
this.$devicePlatformsConstants.Android,
this.$devicePlatformsConstants.visionOS,
this.$devicePlatformsConstants.macOS || "macOS",
];
}

Expand DownExpand Up@@ -48,8 +49,20 @@ export class MobileHelper implements Mobile.IMobileHelper {
);
}

public ismacOSPlatform(platform: string): boolean {
const macOSPlatformName = this.$devicePlatformsConstants.macOS || "macOS";
return !!(
platform &&
macOSPlatformName.toLowerCase() === platform.toLowerCase()
);
}

public isApplePlatform(platform: string): boolean {
return this.isiOSPlatform(platform) || this.isvisionOSPlatform(platform);
return (
this.isiOSPlatform(platform) ||
this.isvisionOSPlatform(platform) ||
this.ismacOSPlatform(platform)
);
}

public normalizePlatformName(platform: string): string {
Expand All@@ -59,6 +72,8 @@ export class MobileHelper implements Mobile.IMobileHelper {
return "iOS";
} else if (this.isvisionOSPlatform(platform)) {
return "visionOS";
} else if (this.ismacOSPlatform(platform)) {
return "macOS";
}

return undefined;
Expand Down
5 changes: 4 additions & 1 deletion lib/constants.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,7 @@ export const TNS_IOS_RUNTIME_NAME = "tns-ios";
export const SCOPED_ANDROID_RUNTIME_NAME = "@nativescript/android";
export const SCOPED_IOS_RUNTIME_NAME = "@nativescript/ios";
export const SCOPED_VISIONOS_RUNTIME_NAME = "@nativescript/visionos";
export const SCOPED_MACOS_RUNTIME_NAME = "@nativescript/macos";
export const PACKAGE_JSON_FILE_NAME = "package.json";
export const PACKAGE_LOCK_JSON_FILE_NAME = "package-lock.json";
export const ANDROID_DEVICE_APP_ROOT_TEMPLATE = `/data/data/%s/files`;
Expand DownExpand Up@@ -348,12 +349,14 @@ export const enum PlatformTypes {
ios = "ios",
android = "android",
visionos = "visionos",
macos = "macos",
}

export type SupportedPlatform =
| PlatformTypes.ios
| PlatformTypes.android
| PlatformTypes.visionos;
| PlatformTypes.visionos
| PlatformTypes.macos;

export const PODFILE_NAME = "Podfile";

Expand Down
51 changes: 51 additions & 0 deletions lib/controllers/prepare-controller.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -194,6 +194,8 @@ export class PrepareController extends EventEmitter {
};
}

this.syncMacOSBundleArtifacts(projectData, platformData);

await this.writeRuntimePackageJson(projectData, platformData, prepareData);

await this.$projectChangesService.savePrepareInfo(
Expand DownExpand Up@@ -518,6 +520,55 @@ export class PrepareController extends EventEmitter {
this.$fs.writeJson(packagePath, packageData);
}

private syncMacOSBundleArtifacts(
projectData: IProjectData,
platformData: IPlatformData,
): void {
if (platformData.platformNameLowerCase !== "macos") {
return;
}
if (process.env.NS_MACOS_IOS_BUNDLE_FALLBACK !== "1") {
return;
}

const macosAppPath = path.join(
platformData.projectRoot,
projectData.projectName,
"app",
);
const hasMacBundle =
this.$fs.exists(path.join(macosAppPath, "bundle.js")) ||
this.$fs.exists(path.join(macosAppPath, "bundle.mjs"));

if (hasMacBundle) {
return;
}

const iosAppPath = path.join(
projectData.platformsDir,
"ios",
projectData.projectName,
"app",
);
if (!this.$fs.exists(iosAppPath)) {
return;
}

this.$logger.trace(
`Copying bundle artifacts from ${iosAppPath} to ${macosAppPath} for macOS prepare.`,
);

this.$fs.ensureDirectoryExists(macosAppPath);
const emittedFiles = this.$fs.enumerateFilesInDirectorySync(iosAppPath);

emittedFiles.forEach((sourcePath) => {
const relativePath = path.relative(iosAppPath, sourcePath);
const destinationPath = path.join(macosAppPath, relativePath);
this.$fs.ensureDirectoryExists(path.dirname(destinationPath));
this.$fs.copyFile(sourcePath, destinationPath);
});
}

private emitPrepareEvent(filesChangeEventData: IFilesChangeEventData) {
if (this.isInitialPrepareReady) {
this.emit(PREPARE_READY_EVENT_NAME, filesChangeEventData);
Expand Down
2 changes: 2 additions & 0 deletions lib/definitions/project.d.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,6 +133,7 @@ interface INsConfigIOS extends INsConfigPlaform {
}

interface INSConfigVisionOS extends INsConfigIOS {}
interface INSConfigMacOS extends INsConfigIOS {}

interface INsConfigAndroid extends INsConfigPlaform {
v8Flags?: string;
Expand DownExpand Up@@ -188,6 +189,7 @@ interface INsConfig {
ios?: INsConfigIOS;
android?: INsConfigAndroid;
visionos?: INSConfigVisionOS;
macos?: INSConfigMacOS;
ignoredNativeDependencies?: string[];
hooks?: INsConfigHooks[];
projectName?: string;
Expand Down
1 change: 1 addition & 0 deletions lib/key-commands/bootstrap.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,3 +21,4 @@ injector.requireCommand("open|ios", path);
injector.requireCommand("open|android", path);
injector.requireCommand("open|visionos", path);
injector.requireCommand("open|vision", path);
injector.requireCommand("open|macos", path);
Loading