From 712daf1ac29d5410fc1ab0bd7e3a688f90a3e399 Mon Sep 17 00:00:00 2001 From: DjDeveloperr Date: Wed, 11 Feb 2026 13:22:28 -0500 Subject: [PATCH 01/11] feat: add macos platform support --- .../__tests__/helpers/platform.spec.ts | 14 ++++++++++ packages/webpack5/src/configuration/base.ts | 15 ++++++---- .../webpack5/src/configuration/javascript.ts | 15 ++++++---- .../webpack5/src/configuration/typescript.ts | 15 ++++++---- packages/webpack5/src/helpers/platform.ts | 10 +++++-- packages/webpack5/src/index.ts | 3 ++ packages/webpack5/src/platforms/macos.ts | 28 +++++++++++++++++++ 7 files changed, 81 insertions(+), 19 deletions(-) create mode 100644 packages/webpack5/src/platforms/macos.ts diff --git a/packages/webpack5/__tests__/helpers/platform.spec.ts b/packages/webpack5/__tests__/helpers/platform.spec.ts index 7c0d985629..1ef2d81509 100644 --- a/packages/webpack5/__tests__/helpers/platform.spec.ts +++ b/packages/webpack5/__tests__/helpers/platform.spec.ts @@ -81,4 +81,18 @@ describe('getDistPath', () => { getValueMock.mockImplementation(getValueMockImpl); }); + + it('is generated for macos', () => { + env.android = false; + env.ios = false; + env.visionos = false; + env.vision = false; + env.macos = true; + + const distPath = getDistPath(); + + expect(distPath).toEqual('platforms/macos/jest/app'); + + env.macos = false; + }); }); diff --git a/packages/webpack5/src/configuration/base.ts b/packages/webpack5/src/configuration/base.ts index 774ae8c2dd..73cbb8b541 100644 --- a/packages/webpack5/src/configuration/base.ts +++ b/packages/webpack5/src/configuration/base.ts @@ -209,12 +209,17 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { // config.entry('globals').add('@nativescript/core/globals/index').end(); - config - .entry('bundle') + const includeCoreGlobals = platform !== 'macos' || env.includeCore === true; + const bundleEntry = config.entry('bundle'); + + if (includeCoreGlobals) { // ensure we load nativescript globals first - .add('@nativescript/core/globals/index') - .add('@nativescript/core/bundle-entry-points') - .add(entryPath); + bundleEntry + .add('@nativescript/core/globals/index') + .add('@nativescript/core/bundle-entry-points'); + } + + bundleEntry.add(entryPath); // Add android app components to the bundle to SBG can generate the java classes if (platform === 'android') { diff --git a/packages/webpack5/src/configuration/javascript.ts b/packages/webpack5/src/configuration/javascript.ts index d0af146957..35355fe8a3 100644 --- a/packages/webpack5/src/configuration/javascript.ts +++ b/packages/webpack5/src/configuration/javascript.ts @@ -1,6 +1,6 @@ import Config from 'webpack-chain'; -import { getEntryPath, getEntryDirPath } from '../helpers/platform'; +import { getEntryPath, getEntryDirPath, getPlatformName } from '../helpers/platform'; import { chainedSetAddAfter } from '../helpers/chain'; import { env as _env, IWebpackEnv } from '../index'; import { ContextExclusionPlugin } from 'webpack'; @@ -20,11 +20,14 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { .plugin(`ContextExclusionPlugin|exclude_files`) .use(ContextExclusionPlugin, [/\b_.+\./]); - chainedSetAddAfter( - config.entry('bundle'), - '@nativescript/core/globals/index', - virtualEntryPath - ); + const includeCoreGlobals = getPlatformName() !== 'macos' || env.includeCore === true; + if (includeCoreGlobals) { + chainedSetAddAfter( + config.entry('bundle'), + '@nativescript/core/globals/index', + virtualEntryPath + ); + } config.when(env.hmr, (config) => { // set up core HMR diff --git a/packages/webpack5/src/configuration/typescript.ts b/packages/webpack5/src/configuration/typescript.ts index 9f7e184b7d..0a174f9148 100644 --- a/packages/webpack5/src/configuration/typescript.ts +++ b/packages/webpack5/src/configuration/typescript.ts @@ -1,6 +1,6 @@ import Config from 'webpack-chain'; -import { getEntryDirPath, getEntryPath } from '../helpers/platform'; +import { getEntryDirPath, getEntryPath, getPlatformName } from '../helpers/platform'; import { chainedSetAddAfter } from '../helpers/chain'; import { env as _env, IWebpackEnv } from '../index'; import { ContextExclusionPlugin } from 'webpack'; @@ -23,11 +23,14 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { .plugin(`ContextExclusionPlugin|exclude_files`) .use(ContextExclusionPlugin, [/\b_.+\./]); - chainedSetAddAfter( - config.entry('bundle'), - '@nativescript/core/globals/index', - virtualEntryPath, - ); + const includeCoreGlobals = getPlatformName() !== 'macos' || env.includeCore === true; + if (includeCoreGlobals) { + chainedSetAddAfter( + config.entry('bundle'), + '@nativescript/core/globals/index', + virtualEntryPath, + ); + } config.when(env.hmr, (config) => { // set up core HMR diff --git a/packages/webpack5/src/helpers/platform.ts b/packages/webpack5/src/helpers/platform.ts index 6a28fdcc9e..391fa775dc 100644 --- a/packages/webpack5/src/helpers/platform.ts +++ b/packages/webpack5/src/helpers/platform.ts @@ -7,6 +7,7 @@ import { env } from '../'; import AndroidPlatform from '../platforms/android'; import iOSPlatform from '../platforms/ios'; +import macOSPlatform from '../platforms/macos'; import visionOSPlatform from '../platforms/visionos'; export interface INativeScriptPlatform { @@ -22,6 +23,7 @@ const platforms: { } = { android: AndroidPlatform, ios: iOSPlatform, + macos: macOSPlatform, visionos: visionOSPlatform, }; @@ -62,9 +64,13 @@ export function getPlatformName(): Platform { return 'ios'; } + if (env?.macos) { + return 'macos'; + } + if (env?.visionos || env?.vision) { return 'visionos'; - } + } // support custom platforms if (env?.platform) { @@ -86,7 +92,7 @@ export function getPlatformName(): Platform { Available platforms: ${Object.keys(platforms).join(', ')} - Use --env.platform= or --env.android, --env.ios, --env.visionos to specify the target platform. + Use --env.platform= or --env.android, --env.ios, --env.macos, --env.visionos to specify the target platform. Defaulting to "ios". `, diff --git a/packages/webpack5/src/index.ts b/packages/webpack5/src/index.ts index 8adc3bfaa8..ff259d6dff 100644 --- a/packages/webpack5/src/index.ts +++ b/packages/webpack5/src/index.ts @@ -33,6 +33,7 @@ export interface IWebpackEnv { android?: boolean; ios?: boolean; + macos?: boolean; // for custom platforms platform?: string; @@ -52,6 +53,8 @@ export interface IWebpackEnv { // enable commonjs modules (default: ES modules, esm) commonjs?: boolean; + // skip core globals/bundle-entry-points for macos unless explicitly enabled + includeCore?: boolean; // misc replace?: string[] | string; diff --git a/packages/webpack5/src/platforms/macos.ts b/packages/webpack5/src/platforms/macos.ts new file mode 100644 index 0000000000..3beeaeccf4 --- /dev/null +++ b/packages/webpack5/src/platforms/macos.ts @@ -0,0 +1,28 @@ +import { basename } from "path"; + +import { INativeScriptPlatform } from "../helpers/platform"; +import { getProjectRootPath } from "../helpers/project"; +import { env } from '../'; +import { getValue } from '../helpers/config'; + +function sanitizeName(appName: string): string { + return appName.split("").filter((c) => + /[a-zA-Z0-9]/.test(c) + ).join(""); +} + +function getDistPath() { + // if nativescript.config projectName is defined, use that custom name + // otherwise, default to base project directory name for project name + const appName = getValue('projectName') ?? sanitizeName(basename(getProjectRootPath())); + const platform = process.env.USER_PROJECT_PLATFORMS_MACOS + ? process.env.USER_PROJECT_PLATFORMS_MACOS + : `${env.buildPath ?? "platforms"}/macos`; + return `${platform}/${appName}/app`; +} + +const macOSPlatform: INativeScriptPlatform = { + getDistPath, +}; + +export default macOSPlatform; From 71a033bfc9e5dd90aa48d22b94c7db60a61e3b1f Mon Sep 17 00:00:00 2001 From: DjDeveloperr Date: Thu, 12 Feb 2026 01:24:24 -0500 Subject: [PATCH 02/11] fix: ignore .node files in webpack --- packages/webpack5/src/configuration/base.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/webpack5/src/configuration/base.ts b/packages/webpack5/src/configuration/base.ts index 73cbb8b541..d2265bbd2d 100644 --- a/packages/webpack5/src/configuration/base.ts +++ b/packages/webpack5/src/configuration/base.ts @@ -114,7 +114,18 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { // package.json is generated by the CLI with runtime options // this ensures it's not included in the bundle, but rather // resolved at runtime - config.externals(['package.json', '~/package.json']); + config.externals([ + 'package.json', + '~/package.json', + // Native addons are runtime-loaded binaries and must not be bundled. + ({ request }, callback) => { + if (request && /\.node(?:[?#].*)?$/.test(request)) { + return callback(null, `commonjs ${request}`); + } + + callback(); + }, + ]); // disable marking built-in node modules as external // since they are not available at runtime and From 5ff0e8a94a726495b754fd115129a3accceef46a Mon Sep 17 00:00:00 2001 From: DjDeveloperr Date: Thu, 12 Feb 2026 21:16:58 -0500 Subject: [PATCH 03/11] feat: add limited macOS support to core and various platform-specific implementations --- .../core/application-settings/index.macos.ts | 1 + .../file-system/file-system-access.macos.ts | 1 + .../core/http/http-request/index.macos.ts | 186 ++++++++++++++++++ packages/core/http/index.macos.ts | 85 ++++++++ packages/core/index.macos.ts | 9 + packages/core/platform/device/index.macos.ts | 64 ++++++ packages/core/platform/index.macos.ts | 16 ++ packages/core/platform/screen/index.macos.ts | 37 ++++ .../platforms/ios/src/NativeScriptEmbedder.h | 3 +- .../platforms/ios/src/NativeScriptEmbedder.m | 2 + .../ios/src/NativeScriptMainWindow.swift | 4 + .../platforms/ios/src/NativeScriptUtils.h | 2 + .../platforms/ios/src/NativeScriptUtils.m | 2 + .../platforms/ios/src/UIView+NativeScript.h | 2 + .../platforms/ios/src/UIView+NativeScript.m | 2 + packages/core/text/index.macos.ts | 1 + packages/core/ui/dialogs/index.macos.ts | 150 ++++++++++++++ packages/core/utils/constants.macos.ts | 7 + packages/core/utils/index.macos.ts | 76 +++++++ packages/core/utils/native-helper.macos.ts | 69 +++++++ packages/webpack5/README.md | 2 +- packages/webpack5/src/configuration/base.ts | 20 +- 22 files changed, 738 insertions(+), 3 deletions(-) create mode 100644 packages/core/application-settings/index.macos.ts create mode 100644 packages/core/file-system/file-system-access.macos.ts create mode 100644 packages/core/http/http-request/index.macos.ts create mode 100644 packages/core/http/index.macos.ts create mode 100644 packages/core/index.macos.ts create mode 100644 packages/core/platform/device/index.macos.ts create mode 100644 packages/core/platform/index.macos.ts create mode 100644 packages/core/platform/screen/index.macos.ts create mode 100644 packages/core/text/index.macos.ts create mode 100644 packages/core/ui/dialogs/index.macos.ts create mode 100644 packages/core/utils/constants.macos.ts create mode 100644 packages/core/utils/index.macos.ts create mode 100644 packages/core/utils/native-helper.macos.ts diff --git a/packages/core/application-settings/index.macos.ts b/packages/core/application-settings/index.macos.ts new file mode 100644 index 0000000000..8067614d5d --- /dev/null +++ b/packages/core/application-settings/index.macos.ts @@ -0,0 +1 @@ +export * from './index.ios'; diff --git a/packages/core/file-system/file-system-access.macos.ts b/packages/core/file-system/file-system-access.macos.ts new file mode 100644 index 0000000000..e9e0e39ab7 --- /dev/null +++ b/packages/core/file-system/file-system-access.macos.ts @@ -0,0 +1 @@ +export * from './file-system-access.ios'; diff --git a/packages/core/http/http-request/index.macos.ts b/packages/core/http/http-request/index.macos.ts new file mode 100644 index 0000000000..e20f2e4ea2 --- /dev/null +++ b/packages/core/http/http-request/index.macos.ts @@ -0,0 +1,186 @@ +import * as types from '../../utils/types'; +import * as domainDebugger from '../../debugger'; +import { getFilenameFromUrl } from './http-request-common'; +import { File } from '../../file-system'; +import type { HttpRequestOptions, HttpResponse, Headers } from '../http-interfaces'; +import { HttpResponseEncoding } from '../http-interfaces'; + +const GET = 'GET'; +const USER_AGENT_HEADER = 'User-Agent'; +const USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko)'; + +const sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration; +const queue = NSOperationQueue.mainQueue; + +function parseJSON(source: string): any { + const src = source.trim(); + if (src.lastIndexOf(')') === src.length - 1) { + return JSON.parse(src.substring(src.indexOf('(') + 1, src.lastIndexOf(')'))); + } + return JSON.parse(src); +} + +let defaultSession: NSURLSession; +function ensureDefaultSession() { + if (!defaultSession) { + defaultSession = NSURLSession.sessionWithConfigurationDelegateDelegateQueue(sessionConfig, null, queue); + } +} + +export function request(options: HttpRequestOptions): Promise { + return new Promise((resolve, reject) => { + if (!options.url) { + reject(new Error('Request url was empty.')); + return; + } + + try { + const network = domainDebugger.getNetwork(); + const debugRequest = network && network.create(); + const urlRequest = NSMutableURLRequest.requestWithURL(NSURL.URLWithString(options.url)); + + urlRequest.HTTPMethod = types.isDefined(options.method) ? options.method : GET; + urlRequest.setValueForHTTPHeaderField(USER_AGENT, USER_AGENT_HEADER); + + if (options.headers) { + for (const header in options.headers) { + urlRequest.setValueForHTTPHeaderField(options.headers[header] + '', header); + } + } + + if (types.isString(options.content) || options.content instanceof FormData) { + urlRequest.HTTPBody = NSString.stringWithString(options.content.toString()).dataUsingEncoding(NSUTF8StringEncoding); + } else if (options.content instanceof ArrayBuffer) { + urlRequest.HTTPBody = NSData.dataWithData(options.content as any); + } + + if (types.isNumber(options.timeout)) { + urlRequest.timeoutInterval = options.timeout / 1000; + } + + ensureDefaultSession(); + + let timestamp = -1; + const dataTask = defaultSession.dataTaskWithRequestCompletionHandler(urlRequest, (data: NSData, response: NSHTTPURLResponse, error: NSError) => { + if (error) { + reject(new Error(error.localizedDescription)); + return; + } + + const headers: Headers = {}; + if (response && response.allHeaderFields) { + const headerFields = response.allHeaderFields; + headerFields.enumerateKeysAndObjectsUsingBlock((key, value) => { + addHeader(headers, key, value); + }); + } + + if (debugRequest) { + debugRequest.mimeType = response.MIMEType; + debugRequest.data = data; + const debugResponse = { + url: options.url, + status: response.statusCode, + statusText: NSHTTPURLResponse.localizedStringForStatusCode(response.statusCode), + headers: headers, + mimeType: response.MIMEType, + fromDiskCache: false, + timing: { + requestTime: timestamp, + proxyStart: -1, + proxyEnd: -1, + dnsStart: -1, + dnsEnd: -1, + connectStart: -1, + connectEnd: -1, + sslStart: -1, + sslEnd: -1, + serviceWorkerFetchStart: -1, + serviceWorkerFetchReady: -1, + serviceWorkerFetchEnd: -1, + sendStart: -1, + sendEnd: -1, + receiveHeadersEnd: -1, + }, + headersSize: headers?.length ?? -1, + }; + debugRequest.responseReceived(debugResponse); + debugRequest.loadingFinished(); + } + + resolve({ + content: { + raw: data, + toArrayBuffer: () => interop.bufferFromData(data), + toString: (encoding?: any) => { + const str = NSDataToString(data, encoding); + if (typeof str === 'string') { + return str; + } + throw new Error('Response content may not be converted to string'); + }, + toJSON: (encoding?: any) => parseJSON(NSDataToString(data, encoding)), + toImage: () => Promise.reject(new Error('Response content may not be converted to an Image on macOS')), + toFile: (destinationFilePath?: string) => { + if (!destinationFilePath) { + destinationFilePath = getFilenameFromUrl(options.url); + } + if (data instanceof NSData) { + const file = File.fromPath(destinationFilePath); + data.writeToFileAtomically(destinationFilePath, true); + return file; + } + throw new Error(`Cannot save file with path: ${destinationFilePath}.`); + }, + }, + statusCode: response.statusCode, + headers: headers, + }); + }); + + if (options.url && debugRequest) { + timestamp = Date.now() / 1000; + const request = { + url: options.url, + method: 'GET', + headers: options.headers, + timestamp, + headersSize: options?.headers?.length ?? -1, + }; + debugRequest.requestWillBeSent(request); + } + + dataTask.resume(); + } catch (ex) { + reject(ex); + } + }); +} + +function NSDataToString(data: any, encoding?: HttpResponseEncoding): string { + let code = NSUTF8StringEncoding; + + if (encoding === HttpResponseEncoding.GBK) { + code = CFStringEncodings.kCFStringEncodingGB_18030_2000; + } + + let encodedString = NSString.alloc().initWithDataEncoding(data, code); + if (!encodedString) { + code = NSISOLatin1StringEncoding; + encodedString = NSString.alloc().initWithDataEncoding(data, code); + } + + return encodedString.toString(); +} + +export function addHeader(headers: Headers, key: string, value: string): void { + if (!headers[key]) { + headers[key] = value; + } else if (Array.isArray(headers[key])) { + (headers[key]).push(value); + } else { + const values: string[] = [headers[key]]; + values.push(value); + headers[key] = values; + } +} diff --git a/packages/core/http/index.macos.ts b/packages/core/http/index.macos.ts new file mode 100644 index 0000000000..fd43bb3f3f --- /dev/null +++ b/packages/core/http/index.macos.ts @@ -0,0 +1,85 @@ +import { type ImageSourceLike } from './http-shared'; +import { request } from './http-request'; +export { request } from './http-request'; +export * from './http-interfaces'; + +export function getString(arg: any): Promise { + return new Promise((resolve, reject) => { + request(typeof arg === 'string' ? { url: arg, method: 'GET' } : arg).then( + (r) => { + try { + const str = r.content.toString(); + resolve(str); + } catch (e) { + reject(e); + } + }, + (e) => reject(e), + ); + }); +} + +export function getJSON(arg: any): Promise { + return new Promise((resolve, reject) => { + request(typeof arg === 'string' ? { url: arg, method: 'GET' } : arg).then( + (r) => { + try { + const json = r.content.toJSON(); + resolve(json); + } catch (e) { + reject(e); + } + }, + (e) => reject(e), + ); + }); +} + +export function getImage(arg: any): Promise { + return new Promise((resolve, reject) => { + request(typeof arg === 'string' ? { url: arg, method: 'GET' } : arg).then( + (r) => { + try { + resolve(r.content.toImage()); + } catch (err) { + reject(err); + } + }, + (err) => { + reject(err); + }, + ); + }); +} + +export function getFile(arg: any, destinationFilePath?: string): Promise { + return new Promise((resolve, reject) => { + request(typeof arg === 'string' ? { url: arg, method: 'GET' } : arg).then( + (r) => { + try { + const file = r.content.toFile(destinationFilePath); + resolve(file); + } catch (e) { + reject(e); + } + }, + (e) => reject(e), + ); + }); +} + +export function getBinary(arg: any): Promise { + return new Promise((resolve, reject) => { + request(typeof arg === 'string' ? { url: arg, method: 'GET' } : arg).then( + (r) => { + try { + const arrayBuffer = r.content.toArrayBuffer(); + resolve(arrayBuffer); + } catch (e) { + reject(e); + } + }, + (e) => reject(e), + ); + }); +} diff --git a/packages/core/index.macos.ts b/packages/core/index.macos.ts new file mode 100644 index 0000000000..896477457f --- /dev/null +++ b/packages/core/index.macos.ts @@ -0,0 +1,9 @@ +export * as ApplicationSettings from './application-settings'; +export { File, FileSystemEntity, Folder, knownFolders, path, getFileAccess, AndroidDirectory } from './file-system'; +export type { HttpRequestOptions, HttpResponse, Headers, HttpContent } from './http/http-interfaces'; +export { HttpResponseEncoding } from './http/http-interfaces'; +export * as Http from './http'; +export { isAndroid, isIOS, isVisionOS, isApple, Screen, Device, platformNames } from './platform'; +export type { IDevice } from './platform'; +export * as Utils from './utils'; +export * as Dialogs from './ui/dialogs'; diff --git a/packages/core/platform/device/index.macos.ts b/packages/core/platform/device/index.macos.ts new file mode 100644 index 0000000000..e0e53defd7 --- /dev/null +++ b/packages/core/platform/device/index.macos.ts @@ -0,0 +1,64 @@ +class DeviceRef { + private _model: string; + private _osVersion: string; + private _sdkVersion: string; + + get manufacturer(): string { + return 'Apple'; + } + + get os(): string { + return 'macOS'; + } + + get osVersion(): string { + if (!this._osVersion) { + const version = NSProcessInfo.processInfo.operatingSystemVersion; + this._osVersion = `${version.majorVersion}.${version.minorVersion}.${version.patchVersion}`; + } + return this._osVersion; + } + + get model(): string { + if (!this._model) { + this._model = NSHost.currentHost.localizedName || 'Mac'; + } + return this._model; + } + + get sdkVersion(): string { + if (!this._sdkVersion) { + this._sdkVersion = this.osVersion; + } + return this._sdkVersion; + } + + get deviceType(): string { + return 'Desktop'; + } + + get uuid(): string { + const userDefaults = NSUserDefaults.standardUserDefaults; + const uuidKey = 'TNSUUID'; + let appUUID = userDefaults.stringForKey(uuidKey); + + if (!appUUID) { + appUUID = NSUUID.UUID().UUIDString; + userDefaults.setObjectForKey(appUUID, uuidKey); + userDefaults.synchronize(); + } + + return appUUID; + } + + get language(): string { + return NSLocale.preferredLanguages[0]; + } + + get region(): string { + return NSLocale.currentLocale.objectForKey(NSLocaleCountryCode); + } +} + +export const Device = new DeviceRef(); +export const device = Device; diff --git a/packages/core/platform/index.macos.ts b/packages/core/platform/index.macos.ts new file mode 100644 index 0000000000..40a6218b5c --- /dev/null +++ b/packages/core/platform/index.macos.ts @@ -0,0 +1,16 @@ +export const platformNames = { + android: 'Android', + ios: 'iOS', + visionos: 'visionOS', + macos: 'macOS', + apple: 'apple', +}; + +export const isAndroid = !!__ANDROID__; +export const isIOS = !!__IOS__; +export const isVisionOS = !!__VISIONOS__; +export const isApple = !!__APPLE__; +export const isMacOS = isApple && !isIOS && !isVisionOS; + +export * from './device'; +export * from './screen'; diff --git a/packages/core/platform/screen/index.macos.ts b/packages/core/platform/screen/index.macos.ts new file mode 100644 index 0000000000..991ad85385 --- /dev/null +++ b/packages/core/platform/screen/index.macos.ts @@ -0,0 +1,37 @@ +class MainScreen { + private get screen(): NSScreen { + if (NSScreen.mainScreen) { + return NSScreen.mainScreen; + } + const screens = NSScreen.screens; + return screens && screens.count > 0 ? screens.objectAtIndex(0) : null; + } + + get widthPixels(): number { + return this.widthDIPs * this.scale; + } + + get heightPixels(): number { + return this.heightDIPs * this.scale; + } + + get scale(): number { + return this.screen ? this.screen.backingScaleFactor : 1; + } + + get widthDIPs(): number { + return this.screen ? this.screen.frame.size.width : 0; + } + + get heightDIPs(): number { + return this.screen ? this.screen.frame.size.height : 0; + } + + public _updateMetrics(): void {} +} + +export class Screen { + static mainScreen = new MainScreen(); +} + +export const screen = Screen; diff --git a/packages/core/platforms/ios/src/NativeScriptEmbedder.h b/packages/core/platforms/ios/src/NativeScriptEmbedder.h index cf8fd71e35..4d12f8f234 100644 --- a/packages/core/platforms/ios/src/NativeScriptEmbedder.h +++ b/packages/core/platforms/ios/src/NativeScriptEmbedder.h @@ -4,6 +4,7 @@ // // Created by Teodor Dermendzhiev on 6/19/18. // +#if __has_include() #include // When embedding NativeScript application embedder needs to conform to this protocol @@ -28,4 +29,4 @@ @end - +#endif diff --git a/packages/core/platforms/ios/src/NativeScriptEmbedder.m b/packages/core/platforms/ios/src/NativeScriptEmbedder.m index 78981bc206..9100260ae3 100644 --- a/packages/core/platforms/ios/src/NativeScriptEmbedder.m +++ b/packages/core/platforms/ios/src/NativeScriptEmbedder.m @@ -1,3 +1,4 @@ +#if __has_include() #import "NativeScriptEmbedder.h" @implementation NativeScriptEmbedder @@ -41,3 +42,4 @@ +(void)boot { // End backwards compat @end +#endif diff --git a/packages/core/platforms/ios/src/NativeScriptMainWindow.swift b/packages/core/platforms/ios/src/NativeScriptMainWindow.swift index f5ea21a104..39feb5cbaa 100644 --- a/packages/core/platforms/ios/src/NativeScriptMainWindow.swift +++ b/packages/core/platforms/ios/src/NativeScriptMainWindow.swift @@ -1,3 +1,6 @@ +// This file is iOS/visionOS-only. When plugins reuse `platforms/ios/src` for macOS, +// the embedder module is not guaranteed to exist and UIKit is unavailable. +#if canImport(UIKit) && canImport(NativeScriptEmbedder) import SwiftUI import NativeScriptEmbedder import UIKit @@ -194,3 +197,4 @@ struct NativeScriptAppView: UIViewRepresentable { // allow NativeScript to override updateData for custom handling @objc public var updateData: ((_ data: NSMutableDictionary) -> Void)? = nil } +#endif diff --git a/packages/core/platforms/ios/src/NativeScriptUtils.h b/packages/core/platforms/ios/src/NativeScriptUtils.h index e741b10d40..a5f2fd7de3 100644 --- a/packages/core/platforms/ios/src/NativeScriptUtils.h +++ b/packages/core/platforms/ios/src/NativeScriptUtils.h @@ -2,6 +2,7 @@ // NativeScriptUtils.h // // Created by Nathan Walker on 2/02/2022. +#if __has_include() #include @interface NativeScriptUtils : NSObject @@ -14,3 +15,4 @@ +(NSData*)getImageData:(UIImage*)image format:(NSString*)format quality:(CGFloat)quality; @end +#endif diff --git a/packages/core/platforms/ios/src/NativeScriptUtils.m b/packages/core/platforms/ios/src/NativeScriptUtils.m index ace5af1165..bc850340b3 100644 --- a/packages/core/platforms/ios/src/NativeScriptUtils.m +++ b/packages/core/platforms/ios/src/NativeScriptUtils.m @@ -1,3 +1,4 @@ +#if __has_include() #import "NativeScriptUtils.h" @implementation NativeScriptUtils @@ -135,3 +136,4 @@ +(NSData*)getImageData:(UIImage*)image format:(NSString*)format quality:(CGFloat } @end +#endif diff --git a/packages/core/platforms/ios/src/UIView+NativeScript.h b/packages/core/platforms/ios/src/UIView+NativeScript.h index 9a07e4d7d3..acafab5825 100644 --- a/packages/core/platforms/ios/src/UIView+NativeScript.h +++ b/packages/core/platforms/ios/src/UIView+NativeScript.h @@ -2,6 +2,7 @@ // UIView+NativeScript.h // // Created by Nathan Walker on 2/02/2022. +#if __has_include() #include @interface UIView (NativeScript) @@ -13,3 +14,4 @@ -(void)nativeScriptSetFormattedTextStroke:(CGFloat)width color:(UIColor*)color; @end +#endif diff --git a/packages/core/platforms/ios/src/UIView+NativeScript.m b/packages/core/platforms/ios/src/UIView+NativeScript.m index f288aeaa55..6e8a074ee4 100644 --- a/packages/core/platforms/ios/src/UIView+NativeScript.m +++ b/packages/core/platforms/ios/src/UIView+NativeScript.m @@ -1,3 +1,4 @@ +#if __has_include() #import #import "UIView+NativeScript.h" #import "NativeScriptUtils.h" @@ -146,3 +147,4 @@ -(void)nativeScriptSetFormattedTextStroke:(CGFloat)width color:(UIColor*)color { } } @end +#endif diff --git a/packages/core/text/index.macos.ts b/packages/core/text/index.macos.ts new file mode 100644 index 0000000000..8067614d5d --- /dev/null +++ b/packages/core/text/index.macos.ts @@ -0,0 +1 @@ +export * from './index.ios'; diff --git a/packages/core/ui/dialogs/index.macos.ts b/packages/core/ui/dialogs/index.macos.ts new file mode 100644 index 0000000000..1b05afc955 --- /dev/null +++ b/packages/core/ui/dialogs/index.macos.ts @@ -0,0 +1,150 @@ +export namespace DialogStrings { + export const STRING = 'string'; + export const PROMPT = 'Prompt'; + export const CONFIRM = 'Confirm'; + export const ALERT = 'Alert'; + export const LOGIN = 'Login'; + export const OK = 'OK'; + export const CANCEL = 'Cancel'; +} + +export namespace inputType { + export const text = 'text'; + export const password = 'password'; + export const email = 'email'; + export const number = 'number'; + export const decimal = 'decimal'; + export const phone = 'phone'; +} + +export namespace capitalizationType { + export const none = 'none'; + export const all = 'all'; + export const sentences = 'sentences'; + export const words = 'words'; +} + +function normalizeDialogOptions(arg: any, defaults: Record) { + if (!arg || typeof arg !== 'object') { + return { + ...defaults, + message: `${arg ?? ''}`, + }; + } + return { + ...defaults, + ...arg, + }; +} + +function runModalAlert(title: string, message: string, buttons: string[]): number { + const alert = NSAlert.alloc().init(); + alert.messageText = title || ''; + alert.informativeText = message || ''; + for (const button of buttons) { + alert.addButtonWithTitle(button); + } + return alert.runModal(); +} + +export function alert(arg: any): Promise { + const options = normalizeDialogOptions(arg, { + title: DialogStrings.ALERT, + okButtonText: DialogStrings.OK, + }); + runModalAlert(options.title, options.message, [options.okButtonText]); + return Promise.resolve(); +} + +export function confirm(arg: any): Promise { + const options = normalizeDialogOptions(arg, { + title: DialogStrings.CONFIRM, + okButtonText: DialogStrings.OK, + cancelButtonText: DialogStrings.CANCEL, + }); + const result = runModalAlert(options.title, options.message, [options.okButtonText, options.cancelButtonText]); + return Promise.resolve(result === NSAlertFirstButtonReturn); +} + +export function prompt(arg: any): Promise<{ result: boolean; text: string }> { + const options = normalizeDialogOptions(arg, { + title: DialogStrings.PROMPT, + okButtonText: DialogStrings.OK, + cancelButtonText: DialogStrings.CANCEL, + defaultText: '', + }); + + const alert = NSAlert.alloc().init(); + alert.messageText = options.title || ''; + alert.informativeText = options.message || ''; + alert.addButtonWithTitle(options.okButtonText); + alert.addButtonWithTitle(options.cancelButtonText); + + const textField = NSTextField.alloc().initWithFrame(NSMakeRect(0, 0, 260, 24)); + textField.stringValue = options.defaultText || ''; + alert.accessoryView = textField; + + const result = alert.runModal() === NSAlertFirstButtonReturn; + return Promise.resolve({ result, text: textField.stringValue }); +} + +export function login(arg: any): Promise<{ result: boolean; userName: string; password: string }> { + const options = normalizeDialogOptions(arg, { + title: DialogStrings.LOGIN, + okButtonText: DialogStrings.OK, + cancelButtonText: DialogStrings.CANCEL, + userName: '', + password: '', + }); + + const alert = NSAlert.alloc().init(); + alert.messageText = options.title || ''; + alert.informativeText = options.message || ''; + alert.addButtonWithTitle(options.okButtonText); + alert.addButtonWithTitle(options.cancelButtonText); + + const container = NSStackView.alloc().initWithFrame(NSMakeRect(0, 0, 260, 52)); + container.orientation = NSUserInterfaceLayoutOrientation.Vertical; + container.spacing = 8; + + const userField = NSTextField.alloc().initWithFrame(NSMakeRect(0, 0, 260, 24)); + userField.placeholderString = options.userNameHint || ''; + userField.stringValue = options.userName || ''; + + const passwordField = NSSecureTextField.alloc().initWithFrame(NSMakeRect(0, 0, 260, 24)); + passwordField.placeholderString = options.passwordHint || ''; + passwordField.stringValue = options.password || ''; + + container.addArrangedSubview(userField); + container.addArrangedSubview(passwordField); + alert.accessoryView = container; + + const ok = alert.runModal() === NSAlertFirstButtonReturn; + return Promise.resolve({ result: ok, userName: userField.stringValue, password: passwordField.stringValue }); +} + +export function action(arg: any): Promise { + const options = normalizeDialogOptions(arg, { + title: '', + message: '', + cancelButtonText: DialogStrings.CANCEL, + actions: [], + }); + const actions = Array.isArray(options.actions) ? options.actions : []; + const buttons = [...actions, options.cancelButtonText]; + const result = runModalAlert(options.title, options.message, buttons); + const index = result - NSAlertFirstButtonReturn; + return Promise.resolve(buttons[index] ?? options.cancelButtonText); +} + +export function getCurrentPage() { + return null; +} + +export const Dialogs = { + alert, + confirm, + prompt, + login, + action, +}; diff --git a/packages/core/utils/constants.macos.ts b/packages/core/utils/constants.macos.ts new file mode 100644 index 0000000000..085f5171ed --- /dev/null +++ b/packages/core/utils/constants.macos.ts @@ -0,0 +1,7 @@ +const version = NSProcessInfo.processInfo.operatingSystemVersion; + +export const SDK_VERSION = parseFloat(`${version.majorVersion}.${version.minorVersion}`); + +export function supportsGlass(): boolean { + return __APPLE__ && SDK_VERSION >= 26; +} diff --git a/packages/core/utils/index.macos.ts b/packages/core/utils/index.macos.ts new file mode 100644 index 0000000000..7799788c09 --- /dev/null +++ b/packages/core/utils/index.macos.ts @@ -0,0 +1,76 @@ +import { platformCheck } from './platform-check'; +import { collections, getCurrentAppPath, getWindow, iOSNativeHelper, isRealDevice, joinPaths, getter } from './native-helper'; + +export * from './types'; +export * from './utils-shared'; +export * from './native-helper'; + +export const ios = { + collections, + getCurrentAppPath, + getWindow, + isRealDevice, + joinPaths, + getter, +}; + +export const android = platformCheck('utils.android'); + +export function openUrl(location: string): boolean { + try { + const value = location?.trim(); + if (!value) { + return false; + } + const url = NSURL.URLWithString(value); + if (!url) { + return false; + } + return NSWorkspace.sharedWorkspace.openURL(url); + } catch { + return false; + } +} + +export function openUrlAsync(location: string): Promise { + return Promise.resolve(openUrl(location)); +} + +export function openFile(filePath: string): boolean { + return openUrl(`file://${filePath}`); +} + +export function GC() { + if (typeof __collect === 'function') { + __collect(); + } +} + +let queuedGCHandle: number; + +export function queueGC(delay = 900) { + clearTimeout(queuedGCHandle); + queuedGCHandle = setTimeout(() => GC(), delay); +} + +export function releaseNativeObject(object: NSObject) { + if (typeof __releaseNativeCounterpart === 'function') { + __releaseNativeCounterpart(object); + } +} + +export const ad = 0; + +export function dismissSoftInput(_nativeView?: NSView): void {} + +export function dismissKeyboard() { + dismissSoftInput(); +} + +export function copyToClipboard(value: string) { + const pasteboard = NSPasteboard.generalPasteboard; + pasteboard.clearContents(); + pasteboard.setStringForType(value, NSPasteboardTypeString); +} + +export { iOSNativeHelper }; diff --git a/packages/core/utils/native-helper.macos.ts b/packages/core/utils/native-helper.macos.ts new file mode 100644 index 0000000000..d7fe8d9b3c --- /dev/null +++ b/packages/core/utils/native-helper.macos.ts @@ -0,0 +1,69 @@ +import { platformCheck } from './platform-check'; + +export function getCurrentAppPath(): string { + if (!global.__dirname) { + global.__dirname = typeof __dirname !== 'undefined' ? __dirname : import.meta.dirname; + } + const currentDir = global.__dirname; + const tnsModulesIndex = currentDir.indexOf('/tns_modules'); + + let appPath = currentDir; + if (tnsModulesIndex !== -1) { + appPath = currentDir.substring(0, tnsModulesIndex); + } + + return appPath; +} + +export function joinPaths(...paths: string[]): string { + if (!paths || paths.length === 0) { + return ''; + } + + return NSString.stringWithString(NSString.pathWithComponents(paths)).stringByStandardizingPath; +} + +export function isRealDevice(): boolean { + return true; +} + +export function getWindow(): NSWindow { + const app = NSApplication.sharedApplication; + if (!app) { + return null; + } + return app.keyWindow || app.mainWindow; +} + +export function getter(_this: any, property: T | { (): T }): T { + if (typeof property === 'function') { + return (<{ (): T }>property).call(_this); + } + return property; +} + +export namespace collections { + export function jsArrayToNSArray(arr: T[]): NSArray { + return NSArray.arrayWithArray(arr); + } + + export function nsArrayToJSArray(arr: NSArray): Array { + const result = []; + if (!arr) { + return result; + } + const count = arr.count; + for (let i = 0; i < count; i++) { + result.push(arr.objectAtIndex(i)); + } + return result; + } +} + +export const iOSNativeHelper = { + getCurrentAppPath, + joinPaths, + getWindow, +}; + +export const android = platformCheck('utils.android'); diff --git a/packages/webpack5/README.md b/packages/webpack5/README.md index 7324ff08d1..ecda3a4c5d 100644 --- a/packages/webpack5/README.md +++ b/packages/webpack5/README.md @@ -68,7 +68,7 @@ Useful globally available variables in your app: | `global.isAndroid` / `__ANDROID__` | `true` when platform is Android | | `global.isIOS` / `__IOS__` | `true` when platform is iOS | | `global.isVisionOS` / `__VISIONOS__` | `true` when platform is visionOS | -| `global.__APPLE__` | `true` when platform is iOS or visionOS | +| `global.__APPLE__` | `true` when platform is iOS, visionOS, or macOS | ## 📚 API diff --git a/packages/webpack5/src/configuration/base.ts b/packages/webpack5/src/configuration/base.ts index d2265bbd2d..644d7b2082 100644 --- a/packages/webpack5/src/configuration/base.ts +++ b/packages/webpack5/src/configuration/base.ts @@ -401,6 +401,21 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { config.resolve.extensions.clear().merge(newExtensions); } + if (platform === 'macos') { + // macOS currently reuses many iOS-flavored JS modules in ecosystem packages. + // Resolve .ios.* as a fallback when .macos.* is missing. + const extensions = config.resolve.extensions.values(); + const newExtensions = []; + extensions.forEach((ext) => { + newExtensions.push(ext); + if (ext.includes('macos')) { + newExtensions.push(ext.replace('macos', 'ios')); + } + }); + + config.resolve.extensions.clear().merge(newExtensions); + } + // base aliases config.resolve.alias.set('~', getEntryDirPath()).set('@', getEntryDirPath()); @@ -668,7 +683,10 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { __ANDROID__: platform === 'android', __IOS__: platform === 'ios', __VISIONOS__: platform === 'visionos', - __APPLE__: platform === 'ios' || platform === 'visionos', + __APPLE__: + platform === 'ios' || + platform === 'visionos' || + platform === 'macos', /* for compat only */ 'global.isAndroid': platform === 'android', /* for compat only */ 'global.isIOS': platform === 'ios' || platform === 'visionos', From 9100ca27547e7df5c5d0eca80ed82b63c64f4da9 Mon Sep 17 00:00:00 2001 From: DjDeveloperr Date: Thu, 12 Feb 2026 22:17:22 -0500 Subject: [PATCH 04/11] feat: enhance platform resolution handling for iOS, macOS, and visionOS --- packages/webpack5/src/configuration/base.ts | 103 ++++++++++---------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/packages/webpack5/src/configuration/base.ts b/packages/webpack5/src/configuration/base.ts index 644d7b2082..f51ad31ee0 100644 --- a/packages/webpack5/src/configuration/base.ts +++ b/packages/webpack5/src/configuration/base.ts @@ -33,9 +33,30 @@ import { getEntryPath, } from '../helpers/platform'; +function isApplePlatform(platform: string): boolean { + return platform === 'ios' || platform === 'visionos' || platform === 'macos'; +} + +function getPlatformResolutionExtensions(platform: string): string[] { + if (platform === 'visionos') { + return ['visionos', 'apple', 'ios']; + } + + if (platform === 'macos') { + return ['macos', 'apple', 'ios']; + } + + if (platform === 'ios') { + return ['ios', 'apple']; + } + + return [platform]; +} + export default function (config: Config, env: IWebpackEnv = _env): Config { const entryPath = getEntryPath(); const platform = getPlatformName(); + const platformResolutionExtensions = getPlatformResolutionExtensions(platform); const outputPath = getAbsoluteDistPath(); const mode = env.production ? 'production' : 'development'; @@ -373,48 +394,30 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { .add(getProjectFilePath('node_modules')) .add('node_modules'); - config.resolve.extensions - .add(`.${platform}.ts`) - .add('.ts') - .add(`.${platform}.js`) - .add('.js') - .add(`.${platform}.mjs`) - .add('.mjs') - .add(`.${platform}.css`) - .add('.css') - .add(`.${platform}.scss`) - .add('.scss') - .add(`.${platform}.json`) - .add('.json'); - - if (platform === 'visionos') { - // visionOS allows for both .ios and .visionos extensions - const extensions = config.resolve.extensions.values(); - const newExtensions = []; - extensions.forEach((ext) => { - newExtensions.push(ext); - if (ext.includes('visionos')) { - newExtensions.push(ext.replace('visionos', 'ios')); - } - }); - - config.resolve.extensions.clear().merge(newExtensions); - } - - if (platform === 'macos') { - // macOS currently reuses many iOS-flavored JS modules in ecosystem packages. - // Resolve .ios.* as a fallback when .macos.* is missing. - const extensions = config.resolve.extensions.values(); - const newExtensions = []; - extensions.forEach((ext) => { - newExtensions.push(ext); - if (ext.includes('macos')) { - newExtensions.push(ext.replace('macos', 'ios')); - } - }); - - config.resolve.extensions.clear().merge(newExtensions); - } + platformResolutionExtensions.forEach((platformTarget) => { + config.resolve.extensions.add(`.${platformTarget}.ts`); + }); + config.resolve.extensions.add('.ts'); + platformResolutionExtensions.forEach((platformTarget) => { + config.resolve.extensions.add(`.${platformTarget}.js`); + }); + config.resolve.extensions.add('.js'); + platformResolutionExtensions.forEach((platformTarget) => { + config.resolve.extensions.add(`.${platformTarget}.mjs`); + }); + config.resolve.extensions.add('.mjs'); + platformResolutionExtensions.forEach((platformTarget) => { + config.resolve.extensions.add(`.${platformTarget}.css`); + }); + config.resolve.extensions.add('.css'); + platformResolutionExtensions.forEach((platformTarget) => { + config.resolve.extensions.add(`.${platformTarget}.scss`); + }); + config.resolve.extensions.add('.scss'); + platformResolutionExtensions.forEach((platformTarget) => { + config.resolve.extensions.add(`.${platformTarget}.json`); + }); + config.resolve.extensions.add('.json'); // base aliases config.resolve.alias.set('~', getEntryDirPath()).set('@', getEntryDirPath()); @@ -546,9 +549,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { // custom resolver to resolve platform extensions in @import statements // ie. @import "foo.css" would import "foo.ios.css" if the platform is ios and it exists resolve(id, baseDir, importOptions) { - const extensions = - platform === 'visionos' ? [platform, 'ios'] : [platform]; - for (const platformTarget of extensions) { + for (const platformTarget of platformResolutionExtensions) { const ext = extname(id); const platformExt = ext ? `.${platformTarget}${ext}` : ''; @@ -628,7 +629,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { config.plugin('PlatformSuffixPlugin').use(PlatformSuffixPlugin, [ { - extensions: platform === 'visionos' ? [platform, 'ios'] : [platform], + extensions: platformResolutionExtensions, }, ]); @@ -640,9 +641,13 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { // Makes sure that require.context will never include code from // another platform (ie .android.ts when building for ios) - const otherPlatformsRE = getAvailablePlatforms() - .filter((platform) => platform !== getPlatformName()) - .join('|'); + const otherPlatforms = getAvailablePlatforms().filter( + (availablePlatform) => availablePlatform !== getPlatformName(), + ); + if (!isApplePlatform(platform) && !otherPlatforms.includes('apple')) { + otherPlatforms.push('apple'); + } + const otherPlatformsRE = otherPlatforms.join('|'); config .plugin('ContextExclusionPlugin|Other_Platforms') From 2ac228f9b7983748c0447d2d7bb9399c367cb64e Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Fri, 13 Feb 2026 16:05:28 -0800 Subject: [PATCH 05/11] chore: webpack 5.1.0-alpha.2 --- packages/webpack5/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webpack5/package.json b/packages/webpack5/package.json index 8f284ac8fe..5e6ba91417 100644 --- a/packages/webpack5/package.json +++ b/packages/webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/webpack", - "version": "5.0.32-next.13", + "version": "5.1.0-alpha.2", "private": false, "main": "dist/index.js", "files": [ From afe91ef9901af2607bca80769641dc121cb12dbf Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Fri, 13 Feb 2026 19:44:48 -0800 Subject: [PATCH 06/11] fix: types and build for macos --- package-lock.json | 434 ++++++++++++++++-- package.json | 4 +- packages/core/platform/device/index.macos.ts | 2 +- packages/core/references.d.ts | 1 + packages/core/ui/dialogs/index.macos.ts | 14 +- packages/core/ui/index.ts | 1 + packages/core/utils/index.macos.ts | 11 +- .../@nativescript+macos-node-api+0.4.0.patch | 225 +++++++++ 8 files changed, 635 insertions(+), 57 deletions(-) create mode 100644 patches/@nativescript+macos-node-api+0.4.0.patch diff --git a/package-lock.json b/package-lock.json index ab79d59288..2deb53214b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "@nativescript/hook": "^3.0.4", + "@nativescript/macos-node-api": "^0.4.0", "@nativescript/nx": "^22.0.0", "@nstudio/focus": "^20.0.2", "@nstudio/nps-i": "~2.0.0", @@ -79,6 +80,7 @@ "nx": "22.0.2", "parse-css": "git+https://github.com/tabatkins/parse-css.git", "parserlib": "^1.1.1", + "patch-package": "^8.0.1", "postcss": "^8.0.0", "postcss-import": "^16.0.0", "postcss-loader": "^8.0.0", @@ -242,24 +244,6 @@ } } }, - "node_modules/@angular-devkit/architect/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/architect/node_modules/jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", @@ -280,22 +264,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@angular-devkit/architect/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular-devkit/architect/node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -6450,6 +6418,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@nativescript/macos-node-api": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nativescript/macos-node-api/-/macos-node-api-0.4.0.tgz", + "integrity": "sha512-UQmVtBdeNiEV/gssJPeXYHInb2RibEb59UVMC+VVjdMSpTpInpXzs6QoHmaAGx/gO6P8U6BRwDjYYZ7OQvi1bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nativescript/objc-node-api": "^1.0.0-alpha.7" + } + }, "node_modules/@nativescript/nx": { "version": "22.0.0", "resolved": "https://registry.npmjs.org/@nativescript/nx/-/nx-22.0.0.tgz", @@ -6470,6 +6448,13 @@ "nx": "^22.0.0" } }, + "node_modules/@nativescript/objc-node-api": { + "version": "1.0.0-alpha.7", + "resolved": "https://registry.npmjs.org/@nativescript/objc-node-api/-/objc-node-api-1.0.0-alpha.7.tgz", + "integrity": "sha512-HCkKX46wmc/Oe+Td958HeRmlqKCKmzeeIm0Kofb8aU+6WqjslLK8xGj6HLQT1SyzLWNQdr3dYp7PLFixMjBymw==", + "dev": true, + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -12791,6 +12776,25 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", @@ -12806,14 +12810,66 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bound/node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound/node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound/node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -14291,6 +14347,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -15687,6 +15761,16 @@ "node": ">=4" } }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "micromatch": "^4.0.2" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -16119,6 +16203,20 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -16388,6 +16486,19 @@ "node": ">=4" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -20127,6 +20238,26 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stable-stringify": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", + "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -20134,6 +20265,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stable-stringify/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/json-stringify-nice": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", @@ -20196,6 +20334,16 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "license": "Public Domain", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -20254,6 +20402,16 @@ "node": ">=0.10.0" } }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -22869,6 +23027,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/omggif": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", @@ -23513,6 +23681,170 @@ "dev": true, "license": "MIT" }, + "node_modules/patch-package": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz", + "integrity": "sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^4.1.2", + "ci-info": "^3.7.0", + "cross-spawn": "^7.0.3", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^10.0.0", + "json-stable-stringify": "^1.0.2", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.6", + "open": "^7.4.2", + "semver": "^7.5.3", + "slash": "^2.0.0", + "tmp": "^0.2.4", + "yaml": "^2.2.2" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "node": ">=14", + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/patch-package/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/patch-package/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/patch-package/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/patch-package/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/patch-package/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/patch-package/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/patch-package/node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/patch-package/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -25488,6 +25820,24 @@ "dev": true, "license": "ISC" }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shady-css-parser": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/shady-css-parser/-/shady-css-parser-0.1.0.tgz", @@ -27037,9 +27387,9 @@ "license": "MIT" }, "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 245d13f5fb..35286f4119 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "setup": "npm run clean && npm install", "setup:yarn": "yarn clean && yarn", "setup:pnpm": "pnpm run clean && pnpm install", - "postinstall": "ts-patch install && husky", + "postinstall": "ts-patch install && husky && patch-package", "start": "nps" }, "private": true, @@ -28,6 +28,7 @@ "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "@nativescript/hook": "^3.0.4", + "@nativescript/macos-node-api": "^0.4.0", "@nativescript/nx": "^22.0.0", "@nstudio/focus": "^20.0.2", "@nstudio/nps-i": "~2.0.0", @@ -86,6 +87,7 @@ "nx": "22.0.2", "parse-css": "git+https://github.com/tabatkins/parse-css.git", "parserlib": "^1.1.1", + "patch-package": "^8.0.1", "postcss": "^8.0.0", "postcss-import": "^16.0.0", "postcss-loader": "^8.0.0", diff --git a/packages/core/platform/device/index.macos.ts b/packages/core/platform/device/index.macos.ts index e0e53defd7..a5a88e53e7 100644 --- a/packages/core/platform/device/index.macos.ts +++ b/packages/core/platform/device/index.macos.ts @@ -21,7 +21,7 @@ class DeviceRef { get model(): string { if (!this._model) { - this._model = NSHost.currentHost.localizedName || 'Mac'; + this._model = NSHost.currentHost.name || 'Mac'; } return this._model; } diff --git a/packages/core/references.d.ts b/packages/core/references.d.ts index 4300b64aee..2b34941997 100644 --- a/packages/core/references.d.ts +++ b/packages/core/references.d.ts @@ -8,3 +8,4 @@ /// /// /// +/// diff --git a/packages/core/ui/dialogs/index.macos.ts b/packages/core/ui/dialogs/index.macos.ts index 1b05afc955..033e535da4 100644 --- a/packages/core/ui/dialogs/index.macos.ts +++ b/packages/core/ui/dialogs/index.macos.ts @@ -38,7 +38,7 @@ function normalizeDialogOptions(arg: any, defaults: Record) { } function runModalAlert(title: string, message: string, buttons: string[]): number { - const alert = NSAlert.alloc().init(); + const alert = NSAlert.alloc().init() as NSAlert; alert.messageText = title || ''; alert.informativeText = message || ''; for (const button of buttons) { @@ -74,13 +74,13 @@ export function prompt(arg: any): Promise<{ result: boolean; text: string }> { defaultText: '', }); - const alert = NSAlert.alloc().init(); + const alert = NSAlert.alloc().init() as NSAlert; alert.messageText = options.title || ''; alert.informativeText = options.message || ''; alert.addButtonWithTitle(options.okButtonText); alert.addButtonWithTitle(options.cancelButtonText); - const textField = NSTextField.alloc().initWithFrame(NSMakeRect(0, 0, 260, 24)); + const textField = (NSTextField.alloc() as unknown as NSTextField).initWithFrame(NSMakeRect(0, 0, 260, 24)); textField.stringValue = options.defaultText || ''; alert.accessoryView = textField; @@ -97,21 +97,21 @@ export function login(arg: any): Promise<{ result: boolean; userName: string; pa password: '', }); - const alert = NSAlert.alloc().init(); + const alert = NSAlert.alloc().init() as NSAlert; alert.messageText = options.title || ''; alert.informativeText = options.message || ''; alert.addButtonWithTitle(options.okButtonText); alert.addButtonWithTitle(options.cancelButtonText); - const container = NSStackView.alloc().initWithFrame(NSMakeRect(0, 0, 260, 52)); + const container = (NSStackView.alloc() as unknown as NSStackView).initWithFrame(NSMakeRect(0, 0, 260, 52)); container.orientation = NSUserInterfaceLayoutOrientation.Vertical; container.spacing = 8; - const userField = NSTextField.alloc().initWithFrame(NSMakeRect(0, 0, 260, 24)); + const userField = (NSTextField.alloc() as unknown as NSTextField).initWithFrame(NSMakeRect(0, 0, 260, 24)); userField.placeholderString = options.userNameHint || ''; userField.stringValue = options.userName || ''; - const passwordField = NSSecureTextField.alloc().initWithFrame(NSMakeRect(0, 0, 260, 24)); + const passwordField = (NSSecureTextField.alloc() as unknown as NSSecureTextField).initWithFrame(NSMakeRect(0, 0, 260, 24)); passwordField.placeholderString = options.passwordHint || ''; passwordField.stringValue = options.password || ''; diff --git a/packages/core/ui/index.ts b/packages/core/ui/index.ts index a98aa04599..ce5b7abf53 100644 --- a/packages/core/ui/index.ts +++ b/packages/core/ui/index.ts @@ -31,6 +31,7 @@ global.alert = uiDialogs.alert; global.confirm = uiDialogs.confirm; // @ts-ignore global.prompt = uiDialogs.prompt; +// @ts-ignore global.login = uiDialogs.login; global.action = uiDialogs.action; // global.registerModule('ui-dialogs', () => uiDialogs); diff --git a/packages/core/utils/index.macos.ts b/packages/core/utils/index.macos.ts index 7799788c09..18b3acc0c9 100644 --- a/packages/core/utils/index.macos.ts +++ b/packages/core/utils/index.macos.ts @@ -1,17 +1,16 @@ import { platformCheck } from './platform-check'; -import { collections, getCurrentAppPath, getWindow, iOSNativeHelper, isRealDevice, joinPaths, getter } from './native-helper'; +import { ios as iosUtils, getWindow, iOSNativeHelper, isRealDevice } from './native-helper'; export * from './types'; export * from './utils-shared'; export * from './native-helper'; export const ios = { - collections, - getCurrentAppPath, + collections: iosUtils.collections, + getCurrentAppPath: iosUtils.getCurrentAppPath, getWindow, isRealDevice, - joinPaths, - getter, + joinPaths: iosUtils.joinPaths, }; export const android = platformCheck('utils.android'); @@ -46,7 +45,7 @@ export function GC() { } } -let queuedGCHandle: number; +let queuedGCHandle: NodeJS.Timeout; export function queueGC(delay = 900) { clearTimeout(queuedGCHandle); diff --git a/patches/@nativescript+macos-node-api+0.4.0.patch b/patches/@nativescript+macos-node-api+0.4.0.patch new file mode 100644 index 0000000000..367c1346f3 --- /dev/null +++ b/patches/@nativescript+macos-node-api+0.4.0.patch @@ -0,0 +1,225 @@ +diff --git a/node_modules/@nativescript/macos-node-api/types/Runtime.d.ts b/node_modules/@nativescript/macos-node-api/types/Runtime.d.ts +index 4542385..1d8b68b 100644 +--- a/node_modules/@nativescript/macos-node-api/types/Runtime.d.ts ++++ b/node_modules/@nativescript/macos-node-api/types/Runtime.d.ts +@@ -6635,16 +6635,12 @@ declare class list_xattrs_result { + declare class tss { + constructor(init?: tss); + oldtss: sel; +- : number; + esp0: number; + ss0: sel; +- : number; + esp1: number; + ss1: sel; +- : number; + esp2: number; + ss2: sel; +- : number; + cr3: number; + eip: number; + eflags: number; +@@ -6657,21 +6653,13 @@ declare class tss { + esi: number; + edi: number; + es: sel; +- : number; + cs: sel; +- : number; + ss: sel; +- : number; + ds: sel; +- : number; + fs: sel; +- : number; + gs: sel; +- : number; + ldt: sel; +- : number; + t: number; +- : number; + io_bmap: number; + } + +@@ -6679,7 +6667,6 @@ declare class unnamed_4496508063133753178 { + constructor(init?: unnamed_4496508063133753178); + offset00: number; + seg: sel; +- : number; + type: number; + dpl: number; + present: number; +@@ -6695,7 +6682,6 @@ declare class unnamed_7391634615231741349 { + dpl: number; + present: number; + limit16: number; +- : number; + stksz: number; + granular: number; + base24: number; +@@ -7289,7 +7275,6 @@ declare class nextvend { + constructor(init?: nextvend); + nv_magic: unknown /* const array */; + nv_version: number; +- : number; + nv_U: unnamed_13354706086260099080; + } + +@@ -8292,7 +8277,6 @@ declare class unnamed_10851913189610803071 { + offset00: number; + seg: sel; + argcnt: number; +- : number; + type: number; + dpl: number; + present: number; +@@ -8381,7 +8365,6 @@ declare class _Unwind_Control_Block { + barrier_cache: unnamed_1963453509088981222; + cleanup_cache: unnamed_2232855473343066318; + pr_cache: unnamed_11615304210804108409; +- : number; + } + + declare class __socket { +@@ -9179,7 +9162,6 @@ declare class tss_desc { + dpl: number; + present: number; + limit16: number; +- : number; + granular: number; + base24: number; + } +@@ -9379,13 +9361,10 @@ declare class panel { + + declare class task_gate { + constructor(init?: task_gate); +- : number; + tss: sel; +- : number; + type: number; + dpl: number; + present: number; +- : number; + } + + declare class tagITEM { +@@ -9816,7 +9795,6 @@ declare class unnamed_3095397964707882416 { + dpl: number; + present: number; + limit16: number; +- : number; + opsz: number; + granular: number; + base24: number; +@@ -13977,10 +13955,8 @@ declare class unnamed_7545270049141253789 { + base00: number; + base16: number; + type: number; +- : number; + present: number; + limit16: number; +- : number; + granular: number; + base24: number; + } +@@ -16140,7 +16116,6 @@ declare class unnamed_17581234035804441709 { + constructor(init?: unnamed_17581234035804441709); + offset00: number; + seg: sel; +- : number; + type: number; + dpl: number; + present: number; +@@ -25574,7 +25549,7 @@ declare function asl_format(msg: interop.PointerConvertible, msg_fmt: string, ti + + declare function asl_encode_buffer(buf: string, len: number): string; + +-declare function asl_decode_buffer(in: string, buf: interop.PointerConvertible, len: interop.PointerConvertible): number; ++declare function asl_decode_buffer(inarg: string, buf: interop.PointerConvertible, len: interop.PointerConvertible): number; + + declare function asl_next(obj: interop.PointerConvertible): interop.Pointer; + +@@ -26164,9 +26139,9 @@ declare function httpUpdate(http: interop.PointerConvertible): interop.Enum number, in_desc: interop.PointerConvertible, out: (p1: interop.PointerConvertible, p2: interop.PointerConvertible, p3: number) => number, out_desc: interop.PointerConvertible): number; ++declare function inflateBack(strm: interop.PointerConvertible, inarg: (p1: interop.PointerConvertible, p2: interop.PointerConvertible) => number, in_desc: interop.PointerConvertible, out: (p1: interop.PointerConvertible, p2: interop.PointerConvertible, p3: number) => number, out_desc: interop.PointerConvertible): number; + + declare function inflateBackEnd(strm: interop.PointerConvertible): number; + +@@ -31742,7 +31717,7 @@ declare function uuid_generate_time(out: unknown /* const array */): void; + + declare function uuid_is_null(uu: unknown /* const array */): number; + +-declare function uuid_parse(in: unknown /* const array */, uu: unknown /* const array */): number; ++declare function uuid_parse(inarg: unknown /* const array */, uu: unknown /* const array */): number; + + declare function uuid_unparse(uu: unknown /* const array */, out: unknown /* const array */): void; + From 7bcea56d87700785323353d89342eaf4c4707323 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Fri, 13 Feb 2026 19:44:59 -0800 Subject: [PATCH 07/11] chore: core 9.1.0-alpha.0 --- packages/core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/package.json b/packages/core/package.json index fdac399908..7a1ddf66d2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/core", - "version": "9.0.14-next.1", + "version": "9.1.0-alpha.0", "description": "A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.", "type": "module", "main": "index", From 58302e2509c51a7a2ca76f43cb0d3d114f8177a9 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Sat, 14 Feb 2026 10:28:20 -0800 Subject: [PATCH 08/11] feat(core): macos impl base --- .../animation-frame/animation-native.macos.ts | 3 + packages/core/application/index.macos.ts | 10 +++ packages/core/color/index.macos.ts | 27 +++++++ packages/core/fps-meter/fps-native.macos.ts | 30 ++++++++ packages/core/timer/index.macos.ts | 1 + packages/core/ui/animation/index.macos.ts | 21 ++++++ packages/core/ui/styling/background.macos.ts | 1 + packages/core/ui/styling/font.macos.ts | 48 +++++++++++++ packages/core/utils/index.macos.ts | 8 +-- .../core/utils/layout-helper/index.macos.ts | 72 +++++++++++++++++++ .../core/utils/mainthread-helper.macos.ts | 17 +++++ 11 files changed, 234 insertions(+), 4 deletions(-) create mode 100644 packages/core/animation-frame/animation-native.macos.ts create mode 100644 packages/core/application/index.macos.ts create mode 100644 packages/core/color/index.macos.ts create mode 100644 packages/core/fps-meter/fps-native.macos.ts create mode 100644 packages/core/timer/index.macos.ts create mode 100644 packages/core/ui/animation/index.macos.ts create mode 100644 packages/core/ui/styling/background.macos.ts create mode 100644 packages/core/ui/styling/font.macos.ts create mode 100644 packages/core/utils/layout-helper/index.macos.ts create mode 100644 packages/core/utils/mainthread-helper.macos.ts diff --git a/packages/core/animation-frame/animation-native.macos.ts b/packages/core/animation-frame/animation-native.macos.ts new file mode 100644 index 0000000000..c7adc0e7f9 --- /dev/null +++ b/packages/core/animation-frame/animation-native.macos.ts @@ -0,0 +1,3 @@ +import { time } from '../profiling'; + +export const getTimeInFrameBase = time; diff --git a/packages/core/application/index.macos.ts b/packages/core/application/index.macos.ts new file mode 100644 index 0000000000..c60a3cc1bf --- /dev/null +++ b/packages/core/application/index.macos.ts @@ -0,0 +1,10 @@ +import { ApplicationCommon } from './application-common'; + +export * from './application-common'; +export * from './application-shims'; + +class MacOSApplication extends ApplicationCommon { + run(): void {} +} + +export const Application = new MacOSApplication(); diff --git a/packages/core/color/index.macos.ts b/packages/core/color/index.macos.ts new file mode 100644 index 0000000000..e7d17172c7 --- /dev/null +++ b/packages/core/color/index.macos.ts @@ -0,0 +1,27 @@ +import { ColorBase } from './color-common'; +import type { IColor } from './color-types'; + +export class Color extends ColorBase implements IColor { + private _macos: NSColor; + + get ios(): any { + if (!this._macos) { + this._macos = NSColor.colorWithSRGBRedGreenBlueAlpha(this.r / 255, this.g / 255, this.b / 255, this.a / 255); + } + + return this._macos; + } + + public static fromIosColor(value: any): Color { + if (!value) { + return null; + } + + const color = value as NSColor; + const r = Math.round((color.redComponent ?? 0) * 255); + const g = Math.round((color.greenComponent ?? 0) * 255); + const b = Math.round((color.blueComponent ?? 0) * 255); + const a = Math.round((color.alphaComponent ?? 1) * 255); + return new Color(a, r, g, b); + } +} diff --git a/packages/core/fps-meter/fps-native.macos.ts b/packages/core/fps-meter/fps-native.macos.ts new file mode 100644 index 0000000000..8a23288ba1 --- /dev/null +++ b/packages/core/fps-meter/fps-native.macos.ts @@ -0,0 +1,30 @@ +export class FPSCallback { + public running = false; + private readonly onFrame: (currentTimeMillis: number) => void; + private handle: any; + + constructor(onFrame: (currentTimeMillis: number) => void) { + this.onFrame = onFrame; + } + + public start() { + if (this.running) { + return; + } + + this.running = true; + this.handle = setInterval(() => { + this.onFrame(Date.now()); + }, 16); + } + + public stop() { + if (!this.running) { + return; + } + + this.running = false; + clearInterval(this.handle); + this.handle = null; + } +} diff --git a/packages/core/timer/index.macos.ts b/packages/core/timer/index.macos.ts new file mode 100644 index 0000000000..8067614d5d --- /dev/null +++ b/packages/core/timer/index.macos.ts @@ -0,0 +1 @@ +export * from './index.ios'; diff --git a/packages/core/ui/animation/index.macos.ts b/packages/core/ui/animation/index.macos.ts new file mode 100644 index 0000000000..d7f18afa06 --- /dev/null +++ b/packages/core/ui/animation/index.macos.ts @@ -0,0 +1,21 @@ +import { AnimationBase, AnimationDefinition, AnimationPromise } from './animation-common'; + +export * from './animation-common'; + +export class Animation extends AnimationBase { + constructor(animationDefinitions: Array, playSequentially?: boolean) { + super(animationDefinitions, playSequentially); + } + + _resolveAnimationCurve(curve: any): any { + return curve; + } + + public play(): AnimationPromise { + return super.play(); + } + + public cancel(): void { + this._rejectAnimationFinishedPromise(); + } +} diff --git a/packages/core/ui/styling/background.macos.ts b/packages/core/ui/styling/background.macos.ts new file mode 100644 index 0000000000..218128e9d3 --- /dev/null +++ b/packages/core/ui/styling/background.macos.ts @@ -0,0 +1 @@ +export * from './background-common'; diff --git a/packages/core/ui/styling/font.macos.ts b/packages/core/ui/styling/font.macos.ts new file mode 100644 index 0000000000..fb1a9cb187 --- /dev/null +++ b/packages/core/ui/styling/font.macos.ts @@ -0,0 +1,48 @@ +import { Font as FontBase, FontStyle, FontVariationSettings, FontWeight, parseFont } from './font-common'; +import { FontStyleType, FontVariationSettingsType, FontWeightType } from './font-interfaces'; + +export { FontStyle, FontVariationSettings, FontWeight, parseFont }; + +export class Font extends FontBase { + static default = new Font(undefined, undefined); + + constructor(family: string, size: number, style?: FontStyleType, weight?: FontWeightType, scale?: number, variationSettings?: Array) { + super(family, size, style, weight, scale, variationSettings); + } + + public withFontFamily(family: string): Font { + return new Font(family, this.fontSize, this.fontStyle, this.fontWeight, this.fontScale, this.fontVariationSettings); + } + + public withFontStyle(style: FontStyleType): Font { + return new Font(this.fontFamily, this.fontSize, style, this.fontWeight, this.fontScale, this.fontVariationSettings); + } + + public withFontWeight(weight: FontWeightType): Font { + return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight, this.fontScale, this.fontVariationSettings); + } + + public withFontSize(size: number): Font { + return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight, this.fontScale, this.fontVariationSettings); + } + + public withFontScale(scale: number): Font { + return new Font(this.fontFamily, this.fontSize, this.fontStyle, this.fontWeight, scale, this.fontVariationSettings); + } + + public withFontVariationSettings(variationSettings: Array | null): Font { + return new Font(this.fontFamily, this.fontSize, this.fontStyle, this.fontWeight, this.fontScale, variationSettings); + } + + getUIFont(defaultFont: any): any { + return defaultFont; + } + + getAndroidTypeface(): any { + return undefined; + } +} + +export namespace ios { + export function registerFont(_fontFile: string) {} +} diff --git a/packages/core/utils/index.macos.ts b/packages/core/utils/index.macos.ts index 18b3acc0c9..0ff389d86d 100644 --- a/packages/core/utils/index.macos.ts +++ b/packages/core/utils/index.macos.ts @@ -1,16 +1,16 @@ import { platformCheck } from './platform-check'; -import { ios as iosUtils, getWindow, iOSNativeHelper, isRealDevice } from './native-helper'; +import { collections, getCurrentAppPath, joinPaths, getWindow, iOSNativeHelper, isRealDevice } from './native-helper.macos'; export * from './types'; export * from './utils-shared'; export * from './native-helper'; export const ios = { - collections: iosUtils.collections, - getCurrentAppPath: iosUtils.getCurrentAppPath, + collections, + getCurrentAppPath, getWindow, isRealDevice, - joinPaths: iosUtils.joinPaths, + joinPaths, }; export const android = platformCheck('utils.android'); diff --git a/packages/core/utils/layout-helper/index.macos.ts b/packages/core/utils/layout-helper/index.macos.ts new file mode 100644 index 0000000000..ebb7137c15 --- /dev/null +++ b/packages/core/utils/layout-helper/index.macos.ts @@ -0,0 +1,72 @@ +import * as layoutCommon from './layout-helper-common'; + +function getMainScreenScale(): number { + return NSScreen.mainScreen?.backingScaleFactor ?? 1; +} + +export namespace layout { + export const MODE_SHIFT = 30; + export const MODE_MASK = 0x3 << MODE_SHIFT; + + export const UNSPECIFIED = 0 << MODE_SHIFT; + export const EXACTLY = 1 << MODE_SHIFT; + export const AT_MOST = 2 << MODE_SHIFT; + + export const MEASURED_HEIGHT_STATE_SHIFT = 0x00000010; + export const MEASURED_STATE_TOO_SMALL = 0x01000000; + export const MEASURED_STATE_MASK = 0xff000000; + export const MEASURED_SIZE_MASK = 0x00ffffff; + + export function getMode(mode: number) { + return layoutCommon.getMode(mode); + } + + export function getMeasureSpecMode(spec: number): number { + return layoutCommon.getMeasureSpecMode(spec); + } + + export function getMeasureSpecSize(spec: number) { + return layoutCommon.getMeasureSpecSize(spec); + } + + export function makeMeasureSpec(size: number, mode: number): number { + return (Math.round(Math.max(0, size)) & ~MODE_MASK) | (mode & MODE_MASK); + } + + export function hasRtlSupport(): boolean { + return true; + } + + export function getDisplayDensity(): number { + return getMainScreenScale(); + } + + export function toDevicePixels(value: number): number { + return value * getMainScreenScale(); + } + + export function toDeviceIndependentPixels(value: number): number { + return value / getMainScreenScale(); + } + + export function round(value: number) { + return layoutCommon.round(value); + } + + export function measureNativeView(nativeView: any, width: number, widthMode: number, height: number, heightMode: number): { width: number; height: number } { + const view = nativeView as NSView; + const fittingSize = view?.fittingSize; + + const measuredWidth = widthMode === EXACTLY ? width : toDevicePixels(fittingSize?.width ?? 0); + const measuredHeight = heightMode === EXACTLY ? height : toDevicePixels(fittingSize?.height ?? 0); + + return { + width: round(measuredWidth), + height: round(measuredHeight), + }; + } + + export function measureSpecToString(measureSpec: number) { + return layoutCommon.measureSpecToString(measureSpec); + } +} diff --git a/packages/core/utils/mainthread-helper.macos.ts b/packages/core/utils/mainthread-helper.macos.ts new file mode 100644 index 0000000000..b22ee551d1 --- /dev/null +++ b/packages/core/utils/mainthread-helper.macos.ts @@ -0,0 +1,17 @@ +export function dispatchToMainThread(func: () => void) { + NSOperationQueue.mainQueue.addOperationWithBlock(func); +} + +export function isMainThread(): boolean { + return NSThread.isMainThread; +} + +export function dispatchToUIThread(func: () => void) { + const runloop = CFRunLoopGetMain(); + if (runloop && func) { + CFRunLoopPerformBlock(runloop, kCFRunLoopDefaultMode, func); + CFRunLoopWakeUp(runloop); + } else if (func) { + func(); + } +} From 37779a51c19c52bf148993312b8238659fc1823b Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Sat, 14 Feb 2026 10:28:43 -0800 Subject: [PATCH 09/11] fix(webpack): macos handling --- .../__snapshots__/base.spec.ts.snap | 1385 ++++++++++++++++- .../__tests__/configuration/base.spec.ts | 16 + packages/webpack5/project.json | 7 + packages/webpack5/src/configuration/base.ts | 49 +- 4 files changed, 1423 insertions(+), 34 deletions(-) diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/base.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/base.spec.ts.snap index 85186700e1..78b5f700d0 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/base.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/base.spec.ts.snap @@ -1,11 +1,12 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`base configuration for android 1`] = ` "{ mode: 'development', externals: [ 'package.json', - '~/package.json' + '~/package.json', + function () { /* omitted long function */ } ], externalsPresets: { node: false @@ -30,8 +31,16 @@ exports[`base configuration for android 1`] = ` clean: true }, resolve: { + fallback: { + module: '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/module.ts' + }, + fullySpecified: false, symlinks: true, alias: { + 'mdn-data/css/properties.json': '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/mdn-data-properties.ts', + 'mdn-data/css/syntaxes.json': '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/mdn-data-syntaxes.ts', + 'mdn-data/css/at-rules.json': '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/mdn-data-at-rules.ts', + module: '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/module.ts', '~': '__jest__/src', '@': '__jest__/src' }, @@ -63,6 +72,13 @@ exports[`base configuration for android 1`] = ` }, module: { rules: [ + /* config.module.rule('esm-extensionless') */ + { + test: /\\.(mjs|js|ts|tsx)$/, + resolve: { + fullySpecified: false + } + }, /* config.module.rule('bundle') */ { enforce: 'post', @@ -105,6 +121,14 @@ exports[`base configuration for android 1`] = ` }, getCustomTransformers: function () { /* omitted long function */ } } + }, + /* config.module.rule('ts').use('native-class-downlevel-loader') */ + { + loader: 'native-class-downlevel-loader' + }, + /* config.module.rule('ts').use('native-class-strip-loader') */ + { + loader: 'native-class-strip-loader' } ] }, @@ -185,7 +209,655 @@ exports[`base configuration for android 1`] = ` }, /* config.module.rule('scss').use('sass-loader') */ { - loader: 'sass-loader' + loader: 'sass-loader', + options: { + implementation: { + load: function () { /* omitted long function */ }, + compile: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + compileString: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + compileAsync: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + compileStringAsync: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + initCompiler: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + initAsyncCompiler: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + Compiler: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + AsyncCompiler: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Value: function Value0() { + }, + SassBoolean: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassArgumentList: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassCalculation: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + CalculationOperation: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + CalculationInterpolation: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassColor: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassFunction: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassMixin: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassList: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassMap: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassNumber: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassString: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + sassNull: {}, + sassTrue: { + value: true + }, + sassFalse: { + value: false + }, + Exception: function () { /* omitted long function */ }, + Logger: { + silent: { + warn: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + debug: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + } + } + }, + NodePackageImporter: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + deprecations: { + 'call-string': { + id: 'call-string', + status: 'active', + description: 'Passing a string directly to meta.call().', + deprecatedIn: { + major: 0, + minor: 0, + patch: 0, + preRelease: [], + build: [], + _version$_text: '0.0.0' + }, + obsoleteIn: { + major: 0, + minor: 0, + patch: 0, + preRelease: [], + build: [], + _version$_text: '0.0.0' + } + }, + elseif: { + id: 'elseif', + status: 'active', + description: '@elseif.', + deprecatedIn: { + major: 1, + minor: 3, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.3.2' + }, + obsoleteIn: { + major: 1, + minor: 3, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.3.2' + } + }, + 'moz-document': { + id: 'moz-document', + status: 'active', + description: '@-moz-document.', + deprecatedIn: { + major: 1, + minor: 7, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.7.2' + }, + obsoleteIn: { + major: 1, + minor: 7, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.7.2' + } + }, + 'relative-canonical': { + id: 'relative-canonical', + status: 'active', + description: 'Imports using relative canonical URLs.', + deprecatedIn: { + major: 1, + minor: 14, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.14.2' + }, + obsoleteIn: { + major: 1, + minor: 14, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.14.2' + } + }, + 'new-global': { + id: 'new-global', + status: 'active', + description: 'Declaring new variables with !global.', + deprecatedIn: { + major: 1, + minor: 17, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.17.2' + }, + obsoleteIn: { + major: 1, + minor: 17, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.17.2' + } + }, + 'color-module-compat': { + id: 'color-module-compat', + status: 'active', + description: 'Using color module functions in place of plain CSS functions.', + deprecatedIn: { + major: 1, + minor: 23, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.23.0' + }, + obsoleteIn: { + major: 1, + minor: 23, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.23.0' + } + }, + 'slash-div': { + id: 'slash-div', + status: 'active', + description: '/ operator for division.', + deprecatedIn: { + major: 1, + minor: 33, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.33.0' + }, + obsoleteIn: { + major: 1, + minor: 33, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.33.0' + } + }, + 'bogus-combinators': { + id: 'bogus-combinators', + status: 'active', + description: 'Leading, trailing, and repeated combinators.', + deprecatedIn: { + major: 1, + minor: 54, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.54.0' + }, + obsoleteIn: { + major: 1, + minor: 54, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.54.0' + } + }, + 'strict-unary': { + id: 'strict-unary', + status: 'active', + description: 'Ambiguous + and - operators.', + deprecatedIn: { + major: 1, + minor: 55, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.55.0' + }, + obsoleteIn: { + major: 1, + minor: 55, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.55.0' + } + }, + 'function-units': { + id: 'function-units', + status: 'active', + description: 'Passing invalid units to built-in functions.', + deprecatedIn: { + major: 1, + minor: 56, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.56.0' + }, + obsoleteIn: { + major: 1, + minor: 56, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.56.0' + } + }, + 'duplicate-var-flags': { + id: 'duplicate-var-flags', + status: 'active', + description: 'Using !default or !global multiple times for one variable.', + deprecatedIn: { + major: 1, + minor: 62, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.62.0' + }, + obsoleteIn: { + major: 1, + minor: 62, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.62.0' + } + }, + 'null-alpha': { + id: 'null-alpha', + status: 'active', + description: 'Passing null as alpha in the JS API.', + deprecatedIn: { + major: 1, + minor: 62, + patch: 3, + preRelease: [], + build: [], + _version$_text: '1.62.3' + }, + obsoleteIn: { + major: 1, + minor: 62, + patch: 3, + preRelease: [], + build: [], + _version$_text: '1.62.3' + } + }, + 'abs-percent': { + id: 'abs-percent', + status: 'active', + description: 'Passing percentages to the Sass abs() function.', + deprecatedIn: { + major: 1, + minor: 65, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.65.0' + }, + obsoleteIn: { + major: 1, + minor: 65, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.65.0' + } + }, + 'fs-importer-cwd': { + id: 'fs-importer-cwd', + status: 'active', + description: 'Using the current working directory as an implicit load path.', + deprecatedIn: { + major: 1, + minor: 73, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.73.0' + }, + obsoleteIn: { + major: 1, + minor: 73, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.73.0' + } + }, + 'css-function-mixin': { + id: 'css-function-mixin', + status: 'active', + description: 'Function and mixin names beginning with --.', + deprecatedIn: { + major: 1, + minor: 76, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.76.0' + }, + obsoleteIn: { + major: 1, + minor: 76, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.76.0' + } + }, + 'mixed-decls': { + id: 'mixed-decls', + status: 'active', + description: 'Declarations after or between nested rules.', + deprecatedIn: { + major: 1, + minor: 77, + patch: 7, + preRelease: [], + build: [], + _version$_text: '1.77.7' + }, + obsoleteIn: { + major: 1, + minor: 77, + patch: 7, + preRelease: [], + build: [], + _version$_text: '1.77.7' + } + }, + 'feature-exists': { + id: 'feature-exists', + status: 'active', + description: 'meta.feature-exists', + deprecatedIn: { + major: 1, + minor: 78, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.78.0' + }, + obsoleteIn: { + major: 1, + minor: 78, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.78.0' + } + }, + 'color-4-api': { + id: 'color-4-api', + status: 'active', + description: 'Certain uses of built-in sass:color functions.', + deprecatedIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + }, + obsoleteIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + } + }, + 'color-functions': { + id: 'color-functions', + status: 'active', + description: 'Using global color functions instead of sass:color.', + deprecatedIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + }, + obsoleteIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + } + }, + 'legacy-js-api': { + id: 'legacy-js-api', + status: 'active', + description: 'Legacy JS API.', + deprecatedIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + }, + obsoleteIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + } + }, + 'import': { + id: 'import', + status: 'active', + description: '@import rules.', + deprecatedIn: { + major: 1, + minor: 80, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.80.0' + }, + obsoleteIn: { + major: 1, + minor: 80, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.80.0' + } + }, + 'global-builtin': { + id: 'global-builtin', + status: 'active', + description: 'Global built-in functions that are available in sass: modules.', + deprecatedIn: { + major: 1, + minor: 80, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.80.0' + }, + obsoleteIn: { + major: 1, + minor: 80, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.80.0' + } + }, + 'type-function': { + id: 'type-function', + status: 'active', + description: 'Functions named "type".', + deprecatedIn: { + major: 1, + minor: 86, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.86.0' + }, + obsoleteIn: { + major: 1, + minor: 86, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.86.0' + } + }, + 'compile-string-relative-url': { + id: 'compile-string-relative-url', + status: 'active', + description: 'Passing a relative url to compileString().', + deprecatedIn: { + major: 1, + minor: 88, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.88.0' + }, + obsoleteIn: { + major: 1, + minor: 88, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.88.0' + } + }, + 'user-authored': { + id: 'user-authored', + status: 'user', + description: null, + deprecatedIn: null, + obsoleteIn: null + } + }, + Version: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + loadParserExports_: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + info: 'dart-sass\\t1.90.0\\t(Sass Compiler)\\t[Dart]\\ndart2js\\t3.8.3\\t(Dart Compiler)\\t[Dart]', + render: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + renderSync: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + types: { + Boolean: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Color: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + List: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Map: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Null: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Number: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + String: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Error: function Error() { [native code] } + }, + NULL: {}, + TRUE: { + value: true + }, + FALSE: { + value: false + }, + cli_pkg_main_0_: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + } + } + } } ] } @@ -228,6 +900,12 @@ exports[`base configuration for android 1`] = ` ] }, plugins: [ + /* config.plugin('FixSourceMapUrlPlugin') */ + new FixSourceMapUrlPlugin( + { + outputPath: '__jest__/platforms/android/app/src/main/assets/app' + } + ), /* config.plugin('ForkTsCheckerWebpackPlugin') */ new ForkTsCheckerWebpackPlugin( { @@ -251,10 +929,10 @@ exports[`base configuration for android 1`] = ` ), /* config.plugin('ContextExclusionPlugin|Other_Platforms') */ new ContextExclusionPlugin( - /\\.(ios|visionos)\\.(\\w+)$/ + /.(ios|macos|visionos|apple).(w+)$/ ), /* config.plugin('DefinePlugin') */ - new DefinePlugin( + new CompatDefinePlugin( { __DEV__: true, __NS_WEBPACK__: true, @@ -263,6 +941,7 @@ exports[`base configuration for android 1`] = ` __CSS_PARSER__: '"css-tree"', __UI_USE_XML_PARSER__: true, __UI_USE_EXTERNAL_RENDERER__: false, + __COMMONJS__: true, __ANDROID__: true, __IOS__: false, __VISIONOS__: false, @@ -333,7 +1012,8 @@ exports[`base configuration for ios 1`] = ` mode: 'development', externals: [ 'package.json', - '~/package.json' + '~/package.json', + function () { /* omitted long function */ } ], externalsPresets: { node: false @@ -358,23 +1038,37 @@ exports[`base configuration for ios 1`] = ` clean: true }, resolve: { + fallback: { + module: '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/module.ts' + }, + fullySpecified: false, symlinks: true, alias: { + 'mdn-data/css/properties.json': '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/mdn-data-properties.ts', + 'mdn-data/css/syntaxes.json': '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/mdn-data-syntaxes.ts', + 'mdn-data/css/at-rules.json': '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/mdn-data-at-rules.ts', + module: '/Users/nstudio/Documents/github/NativeScript/NativeScript/packages/webpack5/src/polyfills/module.ts', '~': '__jest__/src', '@': '__jest__/src' }, extensions: [ '.ios.ts', + '.apple.ts', '.ts', '.ios.js', + '.apple.js', '.js', '.ios.mjs', + '.apple.mjs', '.mjs', '.ios.css', + '.apple.css', '.css', '.ios.scss', + '.apple.scss', '.scss', '.ios.json', + '.apple.json', '.json' ], modules: [ @@ -391,6 +1085,13 @@ exports[`base configuration for ios 1`] = ` }, module: { rules: [ + /* config.module.rule('esm-extensionless') */ + { + test: /\\.(mjs|js|ts|tsx)$/, + resolve: { + fullySpecified: false + } + }, /* config.module.rule('bundle') */ { enforce: 'post', @@ -433,6 +1134,14 @@ exports[`base configuration for ios 1`] = ` }, getCustomTransformers: function () { /* omitted long function */ } } + }, + /* config.module.rule('ts').use('native-class-downlevel-loader') */ + { + loader: 'native-class-downlevel-loader' + }, + /* config.module.rule('ts').use('native-class-strip-loader') */ + { + loader: 'native-class-strip-loader' } ] }, @@ -513,7 +1222,655 @@ exports[`base configuration for ios 1`] = ` }, /* config.module.rule('scss').use('sass-loader') */ { - loader: 'sass-loader' + loader: 'sass-loader', + options: { + implementation: { + load: function () { /* omitted long function */ }, + compile: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + compileString: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + compileAsync: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + compileStringAsync: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + initCompiler: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + initAsyncCompiler: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + Compiler: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + AsyncCompiler: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Value: function Value0() { + }, + SassBoolean: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassArgumentList: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassCalculation: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + CalculationOperation: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + CalculationInterpolation: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassColor: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassFunction: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassMixin: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassList: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassMap: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassNumber: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + SassString: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + sassNull: {}, + sassTrue: { + value: true + }, + sassFalse: { + value: false + }, + Exception: function () { /* omitted long function */ }, + Logger: { + silent: { + warn: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + debug: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + } + } + }, + NodePackageImporter: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + deprecations: { + 'call-string': { + id: 'call-string', + status: 'active', + description: 'Passing a string directly to meta.call().', + deprecatedIn: { + major: 0, + minor: 0, + patch: 0, + preRelease: [], + build: [], + _version$_text: '0.0.0' + }, + obsoleteIn: { + major: 0, + minor: 0, + patch: 0, + preRelease: [], + build: [], + _version$_text: '0.0.0' + } + }, + elseif: { + id: 'elseif', + status: 'active', + description: '@elseif.', + deprecatedIn: { + major: 1, + minor: 3, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.3.2' + }, + obsoleteIn: { + major: 1, + minor: 3, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.3.2' + } + }, + 'moz-document': { + id: 'moz-document', + status: 'active', + description: '@-moz-document.', + deprecatedIn: { + major: 1, + minor: 7, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.7.2' + }, + obsoleteIn: { + major: 1, + minor: 7, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.7.2' + } + }, + 'relative-canonical': { + id: 'relative-canonical', + status: 'active', + description: 'Imports using relative canonical URLs.', + deprecatedIn: { + major: 1, + minor: 14, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.14.2' + }, + obsoleteIn: { + major: 1, + minor: 14, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.14.2' + } + }, + 'new-global': { + id: 'new-global', + status: 'active', + description: 'Declaring new variables with !global.', + deprecatedIn: { + major: 1, + minor: 17, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.17.2' + }, + obsoleteIn: { + major: 1, + minor: 17, + patch: 2, + preRelease: [], + build: [], + _version$_text: '1.17.2' + } + }, + 'color-module-compat': { + id: 'color-module-compat', + status: 'active', + description: 'Using color module functions in place of plain CSS functions.', + deprecatedIn: { + major: 1, + minor: 23, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.23.0' + }, + obsoleteIn: { + major: 1, + minor: 23, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.23.0' + } + }, + 'slash-div': { + id: 'slash-div', + status: 'active', + description: '/ operator for division.', + deprecatedIn: { + major: 1, + minor: 33, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.33.0' + }, + obsoleteIn: { + major: 1, + minor: 33, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.33.0' + } + }, + 'bogus-combinators': { + id: 'bogus-combinators', + status: 'active', + description: 'Leading, trailing, and repeated combinators.', + deprecatedIn: { + major: 1, + minor: 54, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.54.0' + }, + obsoleteIn: { + major: 1, + minor: 54, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.54.0' + } + }, + 'strict-unary': { + id: 'strict-unary', + status: 'active', + description: 'Ambiguous + and - operators.', + deprecatedIn: { + major: 1, + minor: 55, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.55.0' + }, + obsoleteIn: { + major: 1, + minor: 55, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.55.0' + } + }, + 'function-units': { + id: 'function-units', + status: 'active', + description: 'Passing invalid units to built-in functions.', + deprecatedIn: { + major: 1, + minor: 56, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.56.0' + }, + obsoleteIn: { + major: 1, + minor: 56, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.56.0' + } + }, + 'duplicate-var-flags': { + id: 'duplicate-var-flags', + status: 'active', + description: 'Using !default or !global multiple times for one variable.', + deprecatedIn: { + major: 1, + minor: 62, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.62.0' + }, + obsoleteIn: { + major: 1, + minor: 62, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.62.0' + } + }, + 'null-alpha': { + id: 'null-alpha', + status: 'active', + description: 'Passing null as alpha in the JS API.', + deprecatedIn: { + major: 1, + minor: 62, + patch: 3, + preRelease: [], + build: [], + _version$_text: '1.62.3' + }, + obsoleteIn: { + major: 1, + minor: 62, + patch: 3, + preRelease: [], + build: [], + _version$_text: '1.62.3' + } + }, + 'abs-percent': { + id: 'abs-percent', + status: 'active', + description: 'Passing percentages to the Sass abs() function.', + deprecatedIn: { + major: 1, + minor: 65, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.65.0' + }, + obsoleteIn: { + major: 1, + minor: 65, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.65.0' + } + }, + 'fs-importer-cwd': { + id: 'fs-importer-cwd', + status: 'active', + description: 'Using the current working directory as an implicit load path.', + deprecatedIn: { + major: 1, + minor: 73, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.73.0' + }, + obsoleteIn: { + major: 1, + minor: 73, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.73.0' + } + }, + 'css-function-mixin': { + id: 'css-function-mixin', + status: 'active', + description: 'Function and mixin names beginning with --.', + deprecatedIn: { + major: 1, + minor: 76, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.76.0' + }, + obsoleteIn: { + major: 1, + minor: 76, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.76.0' + } + }, + 'mixed-decls': { + id: 'mixed-decls', + status: 'active', + description: 'Declarations after or between nested rules.', + deprecatedIn: { + major: 1, + minor: 77, + patch: 7, + preRelease: [], + build: [], + _version$_text: '1.77.7' + }, + obsoleteIn: { + major: 1, + minor: 77, + patch: 7, + preRelease: [], + build: [], + _version$_text: '1.77.7' + } + }, + 'feature-exists': { + id: 'feature-exists', + status: 'active', + description: 'meta.feature-exists', + deprecatedIn: { + major: 1, + minor: 78, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.78.0' + }, + obsoleteIn: { + major: 1, + minor: 78, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.78.0' + } + }, + 'color-4-api': { + id: 'color-4-api', + status: 'active', + description: 'Certain uses of built-in sass:color functions.', + deprecatedIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + }, + obsoleteIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + } + }, + 'color-functions': { + id: 'color-functions', + status: 'active', + description: 'Using global color functions instead of sass:color.', + deprecatedIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + }, + obsoleteIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + } + }, + 'legacy-js-api': { + id: 'legacy-js-api', + status: 'active', + description: 'Legacy JS API.', + deprecatedIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + }, + obsoleteIn: { + major: 1, + minor: 79, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.79.0' + } + }, + 'import': { + id: 'import', + status: 'active', + description: '@import rules.', + deprecatedIn: { + major: 1, + minor: 80, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.80.0' + }, + obsoleteIn: { + major: 1, + minor: 80, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.80.0' + } + }, + 'global-builtin': { + id: 'global-builtin', + status: 'active', + description: 'Global built-in functions that are available in sass: modules.', + deprecatedIn: { + major: 1, + minor: 80, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.80.0' + }, + obsoleteIn: { + major: 1, + minor: 80, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.80.0' + } + }, + 'type-function': { + id: 'type-function', + status: 'active', + description: 'Functions named "type".', + deprecatedIn: { + major: 1, + minor: 86, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.86.0' + }, + obsoleteIn: { + major: 1, + minor: 86, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.86.0' + } + }, + 'compile-string-relative-url': { + id: 'compile-string-relative-url', + status: 'active', + description: 'Passing a relative url to compileString().', + deprecatedIn: { + major: 1, + minor: 88, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.88.0' + }, + obsoleteIn: { + major: 1, + minor: 88, + patch: 0, + preRelease: [], + build: [], + _version$_text: '1.88.0' + } + }, + 'user-authored': { + id: 'user-authored', + status: 'user', + description: null, + deprecatedIn: null, + obsoleteIn: null + } + }, + Version: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + loadParserExports_: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + info: 'dart-sass\\t1.90.0\\t(Sass Compiler)\\t[Dart]\\ndart2js\\t3.8.3\\t(Dart Compiler)\\t[Dart]', + render: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + renderSync: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + }, + types: { + Boolean: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Color: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + List: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Map: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Null: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Number: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + String: function () { + return _call(f, this, Array.prototype.slice.apply(arguments)); + }, + Error: function Error() { [native code] } + }, + NULL: {}, + TRUE: { + value: true + }, + FALSE: { + value: false + }, + cli_pkg_main_0_: function () { + return _call(f, Array.prototype.slice.apply(arguments)); + } + } + } } ] } @@ -556,6 +1913,12 @@ exports[`base configuration for ios 1`] = ` ] }, plugins: [ + /* config.plugin('FixSourceMapUrlPlugin') */ + new FixSourceMapUrlPlugin( + { + outputPath: '__jest__/platforms/ios/jest/app' + } + ), /* config.plugin('ForkTsCheckerWebpackPlugin') */ new ForkTsCheckerWebpackPlugin( { @@ -569,7 +1932,8 @@ exports[`base configuration for ios 1`] = ` new PlatformSuffixPlugin( { extensions: [ - 'ios' + 'ios', + 'apple' ] } ), @@ -579,10 +1943,10 @@ exports[`base configuration for ios 1`] = ` ), /* config.plugin('ContextExclusionPlugin|Other_Platforms') */ new ContextExclusionPlugin( - /\\.(android|visionos)\\.(\\w+)$/ + /.(android|macos|visionos).(w+)$/ ), /* config.plugin('DefinePlugin') */ - new DefinePlugin( + new CompatDefinePlugin( { __DEV__: true, __NS_WEBPACK__: true, @@ -591,6 +1955,7 @@ exports[`base configuration for ios 1`] = ` __CSS_PARSER__: '"css-tree"', __UI_USE_XML_PARSER__: true, __UI_USE_EXTERNAL_RENDERER__: false, + __COMMONJS__: true, __ANDROID__: false, __IOS__: true, __VISIONOS__: false, diff --git a/packages/webpack5/__tests__/configuration/base.spec.ts b/packages/webpack5/__tests__/configuration/base.spec.ts index c3608705a5..a8616a97df 100644 --- a/packages/webpack5/__tests__/configuration/base.spec.ts +++ b/packages/webpack5/__tests__/configuration/base.spec.ts @@ -223,6 +223,22 @@ describe('base configuration', () => { expect(config.get('devtool')).toBe('hidden-source-map'); }); + it('does not resolve .ios files for macos builds', () => { + init({ + macos: true, + }); + + const config = base(new Config()); + const extensions = config.resolve.extensions.values(); + + expect(extensions).toContain('.macos.ts'); + expect(extensions).toContain('.apple.ts'); + expect(extensions).not.toContain('.ios.ts'); + expect(extensions).toContain('.macos.js'); + expect(extensions).toContain('.apple.js'); + expect(extensions).not.toContain('.ios.js'); + }); + it('includes inspector_modules on android when @nativescript/core version is >= 8.7.0', () => { const getDependencyVersionSpy = jest.spyOn( dependenciesHelpers, diff --git a/packages/webpack5/project.json b/packages/webpack5/project.json index 976ba26943..6f328f97b8 100644 --- a/packages/webpack5/project.json +++ b/packages/webpack5/project.json @@ -44,6 +44,13 @@ ], "generatePackageJson": false } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/packages/webpack5"], + "options": { + "jestConfig": "{projectRoot}/jest.config.js" + } } } } diff --git a/packages/webpack5/src/configuration/base.ts b/packages/webpack5/src/configuration/base.ts index f51ad31ee0..c7406281f2 100644 --- a/packages/webpack5/src/configuration/base.ts +++ b/packages/webpack5/src/configuration/base.ts @@ -43,7 +43,7 @@ function getPlatformResolutionExtensions(platform: string): string[] { } if (platform === 'macos') { - return ['macos', 'apple', 'ios']; + return ['macos', 'apple']; } if (platform === 'ios') { @@ -56,7 +56,8 @@ function getPlatformResolutionExtensions(platform: string): string[] { export default function (config: Config, env: IWebpackEnv = _env): Config { const entryPath = getEntryPath(); const platform = getPlatformName(); - const platformResolutionExtensions = getPlatformResolutionExtensions(platform); + const platformResolutionExtensions = + getPlatformResolutionExtensions(platform); const outputPath = getAbsoluteDistPath(); const mode = env.production ? 'production' : 'development'; @@ -161,21 +162,21 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { // but are required by some packages like css-tree config.resolve.merge({ fallback: { - module: require.resolve('../polyfills/module.js'), + module: require.resolve('../polyfills/module'), }, alias: { // Mock mdn-data modules that css-tree tries to load 'mdn-data/css/properties.json': require.resolve( - '../polyfills/mdn-data-properties.js', + '../polyfills/mdn-data-properties', ), 'mdn-data/css/syntaxes.json': require.resolve( - '../polyfills/mdn-data-syntaxes.js', + '../polyfills/mdn-data-syntaxes', ), 'mdn-data/css/at-rules.json': require.resolve( - '../polyfills/mdn-data-at-rules.js', + '../polyfills/mdn-data-at-rules', ), // Ensure imports of the Node 'module' builtin resolve to our polyfill - module: require.resolve('../polyfills/module.js'), + module: require.resolve('../polyfills/module'), }, // Allow extension-less ESM imports (fixes "fully specified" errors) // Example: '../timer' -> resolves to index..js without requiring explicit extension @@ -431,21 +432,23 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { .add(getProjectFilePath('node_modules')) .add('node_modules'); - config.module - .rule('bundle') - .enforce('post') - .test(entryPath) - .use('app-css-loader') - .loader('app-css-loader') - .options({ - // TODO: allow both visionos and ios to resolve for css - // only resolve .ios css on visionOS for now - // platform: platform === 'visionos' ? 'ios' : platform, - platform, - }) - .end(); + if (platform !== 'macos') { + config.module + .rule('bundle') + .enforce('post') + .test(entryPath) + .use('app-css-loader') + .loader('app-css-loader') + .options({ + // TODO: allow both visionos and ios to resolve for css + // only resolve .ios css on visionOS for now + // platform: platform === 'visionos' ? 'ios' : platform, + platform, + }) + .end(); + } - config.when(env.hmr, (config) => { + config.when(env.hmr && platform !== 'macos', (config) => { config.module .rule('bundle') .use('nativescript-hot-loader') @@ -689,9 +692,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config { __IOS__: platform === 'ios', __VISIONOS__: platform === 'visionos', __APPLE__: - platform === 'ios' || - platform === 'visionos' || - platform === 'macos', + platform === 'ios' || platform === 'visionos' || platform === 'macos', /* for compat only */ 'global.isAndroid': platform === 'android', /* for compat only */ 'global.isIOS': platform === 'ios' || platform === 'visionos', From a958cf197991204c71a3698f6c03dc402c186060 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Sat, 14 Feb 2026 10:28:54 -0800 Subject: [PATCH 10/11] chore: core 9.1.0-alpha.2 --- packages/core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/package.json b/packages/core/package.json index 7a1ddf66d2..9416c8b1fb 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/core", - "version": "9.1.0-alpha.0", + "version": "9.1.0-alpha.2", "description": "A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.", "type": "module", "main": "index", From 76e397555f6f05c09c8166b24104ff726e2e5f47 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Sat, 14 Feb 2026 10:29:04 -0800 Subject: [PATCH 11/11] chore: webpack 5.1.0-alpha.4 --- packages/webpack5/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webpack5/package.json b/packages/webpack5/package.json index 5e6ba91417..5ab8d7bb5b 100644 --- a/packages/webpack5/package.json +++ b/packages/webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/webpack", - "version": "5.1.0-alpha.2", + "version": "5.1.0-alpha.4", "private": false, "main": "dist/index.js", "files": [