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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/core/global-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ declare const __COMMONJS__: boolean;
declare const __ANDROID__: boolean;
declare const __IOS__: boolean;
declare const __VISIONOS__: boolean;
declare const __TVOS__: boolean;
declare const __APPLE__: boolean;

declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): number;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export { ModuleNameResolver } from './module-name-resolver';
export { _setResolver } from './module-name-resolver/helpers';
export type { PlatformContext } from './module-name-resolver';
export type { ModuleListProvider } from './module-name-resolver/helpers';
export { isAndroid, isIOS, isVisionOS, isApple, Screen, Device, platformNames } from './platform';
export { isAndroid, isIOS, isVisionOS, isTvOS, isApple, Screen, Device, platformNames } from './platform';
export type { IDevice } from './platform';
export { profile, enable as profilingEnable, disable as profilingDisable, time as profilingTime, uptime as profilingUptime, start as profilingStart, stop as profilingStop, isRunning as profilingIsRunning, dumpProfiles as profilingDumpProfiles, resetProfiles as profilingResetProfiles, startCPUProfile as profilingStartCPU, stopCPUProfile as profilingStopCPU } from './profiling';
export type { InstrumentationMode, TimerInfo } from './profiling';
Expand Down
15 changes: 12 additions & 3 deletions packages/core/module-name-resolver/qualifier-matcher/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,24 @@ const minHeightQualifier: QualifierSpec = {

const platformQualifier: QualifierSpec = {
isMatch: function (path: string): boolean {
return path.includes('.android') || path.includes('.ios');
return path.includes('.android') || path.includes('.ios') || path.includes('.tvos');
},
getMatchOccurences: function (path: string): Array<string> {
return path.match(new RegExp('\\.android|\\.ios', 'g'));
return path.match(new RegExp('\\.android|\\.ios|\\.tvos', 'g'));
},
getMatchValue(value: string, context: PlatformContext): number {
const val = value.substring(1);
const os = context.os.toLowerCase();
if (val === os) {
// exact platform: .tvos on tvOS, .ios on iOS, .android on Android
return 2;
}
if (val === 'ios' && os === 'tvos') {
// tvOS falls back to .ios files, below an explicit .tvos candidate
return 1;
}

return val === context.os.toLowerCase() ? 1 : -1;
return -1;
},
};

Expand Down
27 changes: 27 additions & 0 deletions packages/core/platform/common.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { afterEach, describe, expect, it, vi } from 'vitest';

afterEach(() => {
vi.unstubAllGlobals();
vi.resetModules();
});

describe('tvOS platform identity', () => {
it('loads with bundlers that do not define the new tvOS flag', async () => {
delete (globalThis as any).__TVOS__;
const platform = await import('./common');
expect(platform.isTvOS).toBe(false);
const { Device } = await import('./device/index.ios');
expect(Device.os).toBe('iOS');
});

it('recognizes tvOS as both tvOS and iOS-compatible', async () => {
vi.stubGlobal('__TVOS__', true);
vi.stubGlobal('__IOS__', false);
vi.stubGlobal('__VISIONOS__', false);
const platform = await import('./common');
expect(platform.isTvOS).toBe(true);
expect(platform.isIOS).toBe(true);
const { Device } = await import('./device/index.ios');
expect(Device.os).toBe('tvOS');
});
});
4 changes: 3 additions & 1 deletion packages/core/platform/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ export const platformNames = {
android: 'Android',
ios: 'iOS',
visionos: 'visionOS',
tvos: 'tvOS',
apple: 'apple',
};

export const isAndroid = !!__ANDROID__;
export const isIOS = !!__IOS__ || !!__VISIONOS__;
export const isTvOS = typeof __TVOS__ !== 'undefined' && !!__TVOS__;
export const isIOS = !!__IOS__ || !!__VISIONOS__ || isTvOS;
export const isVisionOS = !!__VISIONOS__;
export const isApple = !!__APPLE__;
4 changes: 3 additions & 1 deletion packages/core/platform/device/index.ios.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { platformNames } from '../common';
import { isTvOS, platformNames } from '../common';

type DeviceType = 'Phone' | 'Tablet' | 'Vision';

Expand All @@ -15,6 +15,8 @@ class DeviceRef {
get os(): string {
if (__VISIONOS__) {
return platformNames.visionos;
} else if (isTvOS) {
return platformNames.tvos;
} else {
return platformNames.ios;
}
Expand Down
5 changes: 5 additions & 0 deletions packages/core/platform/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export const isApple: boolean;
*/
export const isVisionOS: boolean;

/**
* Gets a value indicating if the app is running on the tvOS platform.
*/
export const isTvOS: boolean;

export * from './common';
export * from './device';
export * from './screen';
31 changes: 31 additions & 0 deletions packages/core/platforms/ios/NSCWinterTC.xcframework/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,37 @@
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>NSCWinterTC.framework/NSCWinterTC</string>
<key>LibraryIdentifier</key>
<string>tvos-arm64</string>
<key>LibraryPath</key>
<string>NSCWinterTC.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>tvos</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>NSCWinterTC.framework/NSCWinterTC</string>
<key>LibraryIdentifier</key>
<string>tvos-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>NSCWinterTC.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>tvos</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// NSCCrypto.h
// NSCWinterTC
//
// Created by Osei Fortune on 03/07/2024.
// Copyright © 2024 NativeScript. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>
#import <Security/Security.h>
#import <Security/SecItem.h>
#ifndef NSCCrypto_h
#define NSCCrypto_h

typedef enum : NSUInteger {
kNSCCryptoRSASSA_PKCS1_v1_5,
kNSCCryptoRSA_PSS,
kNSCCryptoRSA_OAEP,
} NSCCryptoRsaHashedKeyGenParamsName;


typedef enum : NSUInteger {
kNSCCryptoHashSHA1,
kNSCCryptoHashSHA256,
kNSCCryptoHashSHA384,
kNSCCryptoHashSHA512
} NSCCryptoHash;


typedef enum : NSUInteger {
kNSCCryptoDecrypt,
kNSCCryptoEncrypt,
kNSCCryptoSign,
kNSCCryptoVerify,
kNSCCryptoDeriveKey,
kNSCCryptoDeriveBits,
kNSCCryptoWrapKey,
kNSCCryptoUnwrapKey,
} NSCCryptoKeyUsages;



@interface NSCCryptoKeyPair : NSObject
@property (nonatomic, readonly, nonnull) SecKeyRef privateKey;
@property (nonatomic, readonly, nonnull) SecKeyRef publicKey;
-(nonnull id)initWithPrivateKey:(nonnull SecKeyRef)privKey andPublicKey:(nonnull SecKeyRef)pubKey;
@end

typedef void (^DigestCompletionHandler)(NSData * _Nullable result,NSError * _Nullable error);
typedef void (^GenerateKeyCompletionHandler)(NSCCryptoKeyPair * _Nullable result,NSError * _Nullable error);
typedef void (^DecryptCompletionHandler)(NSData * _Nullable result,NSError * _Nullable error);
typedef void (^EncryptCompletionHandler)(NSData * _Nullable result,NSError * _Nullable error);


@interface NSCCrypto:NSObject
+ (nonnull NSString*)randomUUID;
+ (nullable NSString*)getRandomValues:(nonnull NSMutableData*)buffer;
+ (nullable NSData*)digest:(nonnull NSData*)data mode:(int)mode;
+ (void)digest:(nonnull NSData*)data mode:(int)mode completion:(DigestCompletionHandler _Nonnull ) completion;
+ (nullable NSData *)generateKeyHmac:(int)hash length:(int)length;
+ (nullable NSData *)signHmac:(nonnull NSData*)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data;
+ (BOOL)verifyHmac:(nonnull NSData*)key hash:(NSCCryptoHash)hash signature:(nonnull NSData*)signature data:(nonnull NSData*)data;

+ (nullable NSCCryptoKeyPair*)generateKeyRsa:(NSCCryptoRsaHashedKeyGenParamsName)name modulusLength:(unsigned int)modulusLength publicExponent:(nullable void*)exponent size:(unsigned int)size hash:(NSCCryptoHash)hash extractable:(BOOL)extractable keyUsages:(nonnull NSArray*) usages;

+ (void)generateKeyRsa:(NSCCryptoRsaHashedKeyGenParamsName)name modulusLength:(unsigned int)modulusLength publicExponent:(nullable void*)exponent size:(unsigned int)size hash:(NSCCryptoHash)hash extractable:(BOOL)extractable keyUsages:(nonnull NSArray*) usages completion:(GenerateKeyCompletionHandler _Nonnull ) completion;



+ (nullable NSData *)encryptRsa:(BOOL)isPrivate key:(nonnull NSCCryptoKeyPair *)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data;

+ (void)encryptRsa:(BOOL)isPrivate key:(nonnull NSCCryptoKeyPair *)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data completion:(EncryptCompletionHandler _Nonnull ) completion;

+ (nullable NSData *)decryptRsa:(BOOL)isPrivate key:(nonnull NSCCryptoKeyPair *)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data;

+ (void)decryptRsa:(BOOL)isPrivate key:(nonnull NSCCryptoKeyPair *)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data completion:(DecryptCompletionHandler _Nonnull ) completion;
@end
#endif /* NSCCrypto_h */
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// NSCWinterTC.h
// NSCWinterTC
//
// Created by Osei Fortune and Nathan Walker on 07/09/2024.
// Copyright © 2024 NativeScript. All rights reserved.
//

#import <UIKit/UIKit.h>

//! Project version number for NSCWinterTC.
FOUNDATION_EXPORT double NSCWinterTCVersionNumber;

//! Project version string for NSCWinterTC.
FOUNDATION_EXPORT const unsigned char NSCWinterTCVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <NSCWinterTC/PublicHeader.h>

#import "NSCCrypto.h"
#import "NSString+WinterTC.h"
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// NSString+WinterTC.h
// NSCWinterTC
//
// Created by Osei Fortune and Nathan Walker on 07/09/2024.
// Copyright © 2024 NativeScript. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSString (WinterTC)

+ (NSString*)atob:(nonnull NSString*)data;

+ (NSString*)btoa:(nonnull NSString*)stringToEncode;

@end

NS_ASSUME_NONNULL_END
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
framework module NSCWinterTC {
umbrella header "NSCWinterTC.h"
export *

module * { export * }
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// NSCCrypto.h
// NSCWinterTC
//
// Created by Osei Fortune on 03/07/2024.
// Copyright © 2024 NativeScript. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>
#import <Security/Security.h>
#import <Security/SecItem.h>
#ifndef NSCCrypto_h
#define NSCCrypto_h

typedef enum : NSUInteger {
kNSCCryptoRSASSA_PKCS1_v1_5,
kNSCCryptoRSA_PSS,
kNSCCryptoRSA_OAEP,
} NSCCryptoRsaHashedKeyGenParamsName;


typedef enum : NSUInteger {
kNSCCryptoHashSHA1,
kNSCCryptoHashSHA256,
kNSCCryptoHashSHA384,
kNSCCryptoHashSHA512
} NSCCryptoHash;


typedef enum : NSUInteger {
kNSCCryptoDecrypt,
kNSCCryptoEncrypt,
kNSCCryptoSign,
kNSCCryptoVerify,
kNSCCryptoDeriveKey,
kNSCCryptoDeriveBits,
kNSCCryptoWrapKey,
kNSCCryptoUnwrapKey,
} NSCCryptoKeyUsages;



@interface NSCCryptoKeyPair : NSObject
@property (nonatomic, readonly, nonnull) SecKeyRef privateKey;
@property (nonatomic, readonly, nonnull) SecKeyRef publicKey;
-(nonnull id)initWithPrivateKey:(nonnull SecKeyRef)privKey andPublicKey:(nonnull SecKeyRef)pubKey;
@end

typedef void (^DigestCompletionHandler)(NSData * _Nullable result,NSError * _Nullable error);
typedef void (^GenerateKeyCompletionHandler)(NSCCryptoKeyPair * _Nullable result,NSError * _Nullable error);
typedef void (^DecryptCompletionHandler)(NSData * _Nullable result,NSError * _Nullable error);
typedef void (^EncryptCompletionHandler)(NSData * _Nullable result,NSError * _Nullable error);


@interface NSCCrypto:NSObject
+ (nonnull NSString*)randomUUID;
+ (nullable NSString*)getRandomValues:(nonnull NSMutableData*)buffer;
+ (nullable NSData*)digest:(nonnull NSData*)data mode:(int)mode;
+ (void)digest:(nonnull NSData*)data mode:(int)mode completion:(DigestCompletionHandler _Nonnull ) completion;
+ (nullable NSData *)generateKeyHmac:(int)hash length:(int)length;
+ (nullable NSData *)signHmac:(nonnull NSData*)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data;
+ (BOOL)verifyHmac:(nonnull NSData*)key hash:(NSCCryptoHash)hash signature:(nonnull NSData*)signature data:(nonnull NSData*)data;

+ (nullable NSCCryptoKeyPair*)generateKeyRsa:(NSCCryptoRsaHashedKeyGenParamsName)name modulusLength:(unsigned int)modulusLength publicExponent:(nullable void*)exponent size:(unsigned int)size hash:(NSCCryptoHash)hash extractable:(BOOL)extractable keyUsages:(nonnull NSArray*) usages;

+ (void)generateKeyRsa:(NSCCryptoRsaHashedKeyGenParamsName)name modulusLength:(unsigned int)modulusLength publicExponent:(nullable void*)exponent size:(unsigned int)size hash:(NSCCryptoHash)hash extractable:(BOOL)extractable keyUsages:(nonnull NSArray*) usages completion:(GenerateKeyCompletionHandler _Nonnull ) completion;



+ (nullable NSData *)encryptRsa:(BOOL)isPrivate key:(nonnull NSCCryptoKeyPair *)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data;

+ (void)encryptRsa:(BOOL)isPrivate key:(nonnull NSCCryptoKeyPair *)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data completion:(EncryptCompletionHandler _Nonnull ) completion;

+ (nullable NSData *)decryptRsa:(BOOL)isPrivate key:(nonnull NSCCryptoKeyPair *)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data;

+ (void)decryptRsa:(BOOL)isPrivate key:(nonnull NSCCryptoKeyPair *)key hash:(NSCCryptoHash)hash data:(nonnull NSData*)data completion:(DecryptCompletionHandler _Nonnull ) completion;
@end
#endif /* NSCCrypto_h */
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// NSCWinterTC.h
// NSCWinterTC
//
// Created by Osei Fortune and Nathan Walker on 07/09/2024.
// Copyright © 2024 NativeScript. All rights reserved.
//

#import <UIKit/UIKit.h>

//! Project version number for NSCWinterTC.
FOUNDATION_EXPORT double NSCWinterTCVersionNumber;

//! Project version string for NSCWinterTC.
FOUNDATION_EXPORT const unsigned char NSCWinterTCVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <NSCWinterTC/PublicHeader.h>

#import "NSCCrypto.h"
#import "NSString+WinterTC.h"
Loading