Skip to content

Commit 27ca961

Browse files
Merge pull request #4492 from NativeScript/fatme/kinvey-schema
feat(kinvey): provide correct data to preview-sdk based on the schema
2 parents 882ca60 + ad2a4df commit 27ca961

13 files changed

+206
-47
lines changed

lib/bootstrap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ $injector.require("previewAppLiveSyncService", "./services/livesync/playground/p
140140
$injector.require("previewAppLogProvider", "./services/livesync/playground/preview-app-log-provider");
141141
$injector.require("previewAppPluginsService", "./services/livesync/playground/preview-app-plugins-service");
142142
$injector.require("previewSdkService", "./services/livesync/playground/preview-sdk-service");
143+
$injector.require("previewSchemaService", "./services/livesync/playground/preview-schema-service");
143144
$injector.requirePublicClass("previewDevicesService", "./services/livesync/playground/devices/preview-devices-service");
144145
$injector.requirePublic("previewQrCodeService", "./services/livesync/playground/preview-qr-code-service");
145146
$injector.requirePublic("sysInfo", "./sys-info");

lib/definitions/preview-app-livesync.d.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ declare global {
2222

2323
interface IPreviewSdkService extends EventEmitter {
2424
getQrCodeUrl(options: IGetQrCodeUrlOptions): string;
25-
initialize(getInitialFiles: (device: Device) => Promise<FilesPayload>): void;
25+
initialize(projectDir: string, getInitialFiles: (device: Device) => Promise<FilesPayload>): void;
2626
applyChanges(filesPayload: FilesPayload): Promise<void>;
2727
stop(): void;
2828
}
@@ -45,7 +45,7 @@ declare global {
4545
printLiveSyncQrCode(options: IPrintLiveSyncOptions): Promise<void>;
4646
}
4747

48-
interface IPlaygroundAppQrCodeOptions {
48+
interface IPlaygroundAppQrCodeOptions extends IProjectDir {
4949
platform?: string;
5050
}
5151

@@ -64,4 +64,20 @@ declare global {
6464
getDevicesForPlatform(platform: string): Device[];
6565
getPluginsUsageWarnings(data: IPreviewAppLiveSyncData, device: Device): string[];
6666
}
67+
68+
interface IPreviewSchemaService {
69+
getSchemaData(projectDir: string): IPreviewSchemaData;
70+
}
71+
72+
interface IPreviewSchemaData {
73+
name: string;
74+
scannerAppId: string;
75+
scannerAppStoreId: string;
76+
previewAppId: string;
77+
previewAppStoreId: string;
78+
msvKey: string;
79+
publishKey: string;
80+
subscribeKey: string;
81+
default?: boolean;
82+
}
6783
}

lib/services/livesync/playground/preview-app-constants.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ export class PubnubKeys {
88
public static SUBSCRIBE_KEY = "sub-c-3dad1ebe-aaa3-11e8-8027-363023237e0b";
99
}
1010

11-
export class PlaygroundStoreUrls {
12-
public static GOOGLE_PLAY_URL = "https://play.google.com/store/apps/details?id=org.nativescript.play";
13-
public static APP_STORE_URL = "https://itunes.apple.com/us/app/nativescript-playground/id1263543946?mt=8&ls=1";
14-
}
15-
1611
export class PluginComparisonMessages {
1712
public static PLUGIN_NOT_INCLUDED_IN_PREVIEW_APP = "Plugin %s is not included in preview app on device %s and will not work.";
1813
public static LOCAL_PLUGIN_WITH_DIFFERENCE_IN_MAJOR_VERSION = "Local plugin %s differs in major version from plugin in preview app. The local plugin has version %s and the plugin in preview app has version %s. Some features might not work as expected.";

lib/services/livesync/playground/preview-app-livesync-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class PreviewAppLiveSyncService extends EventEmitter implements IPreviewA
2828

2929
@performanceLog()
3030
public async initialize(data: IPreviewAppLiveSyncData): Promise<void> {
31-
await this.$previewSdkService.initialize(async (device: Device) => {
31+
await this.$previewSdkService.initialize(data.projectDir, async (device: Device) => {
3232
try {
3333
if (!device) {
3434
this.$errors.failWithoutHelp("Sending initial preview files without a specified device is not supported.");

lib/services/livesync/playground/preview-qr-code-service.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as util from "util";
22
import { EOL } from "os";
3-
import { PlaygroundStoreUrls } from "./preview-app-constants";
43
import { exported } from "../../../common/decorators";
54

65
export class PreviewQrCodeService implements IPreviewQrCodeService {
@@ -10,20 +9,22 @@ export class PreviewQrCodeService implements IPreviewQrCodeService {
109
private $logger: ILogger,
1110
private $mobileHelper: Mobile.IMobileHelper,
1211
private $previewSdkService: IPreviewSdkService,
12+
private $previewSchemaService: IPreviewSchemaService,
1313
private $qrCodeTerminalService: IQrCodeTerminalService,
1414
private $qr: IQrCodeGenerator
1515
) { }
1616

1717
@exported("previewQrCodeService")
1818
public async getPlaygroundAppQrCode(options?: IPlaygroundAppQrCodeOptions): Promise<IDictionary<IQrCodeImageData>> {
19+
const { projectDir } = options;
1920
const result = Object.create(null);
2021

2122
if (!options || !options.platform || this.$mobileHelper.isAndroidPlatform(options.platform)) {
22-
result.android = await this.getLiveSyncQrCode(PlaygroundStoreUrls.GOOGLE_PLAY_URL);
23+
result.android = await this.getLiveSyncQrCode(this.getGooglePlayUrl(projectDir));
2324
}
2425

2526
if (!options || !options.platform || this.$mobileHelper.isiOSPlatform(options.platform)) {
26-
result.ios = await this.getLiveSyncQrCode(PlaygroundStoreUrls.APP_STORE_URL);
27+
result.ios = await this.getLiveSyncQrCode(this.getAppStoreUrl(projectDir));
2728
}
2829

2930
return result;
@@ -56,8 +57,8 @@ export class PreviewQrCodeService implements IPreviewQrCodeService {
5657
this.$logger.printMarkdown(`# Use \`NativeScript Playground app\` and scan the \`QR code\` above to preview the application on your device.`);
5758
this.$logger.printMarkdown(`
5859
To scan the QR code and deploy your app on a device, you need to have the \`NativeScript Playground app\`:
59-
App Store (iOS): ${PlaygroundStoreUrls.APP_STORE_URL}
60-
Google Play (Android): ${PlaygroundStoreUrls.GOOGLE_PLAY_URL}`);
60+
App Store (iOS): ${this.getAppStoreUrl(options.projectDir)}
61+
Google Play (Android): ${this.getGooglePlayUrl(options.projectDir)}`);
6162
}
6263
}
6364

@@ -73,5 +74,15 @@ To scan the QR code and deploy your app on a device, you need to have the \`Nati
7374

7475
return url;
7576
}
77+
78+
private getGooglePlayUrl(projectDir: string): string {
79+
const schema = this.$previewSchemaService.getSchemaData(projectDir);
80+
return `https://play.google.com/store/apps/details?id=${schema.scannerAppId}`;
81+
}
82+
83+
private getAppStoreUrl(projectDir: string): string {
84+
const schema = this.$previewSchemaService.getSchemaData(projectDir);
85+
return `https://itunes.apple.com/us/app/nativescript-playground/id${schema.scannerAppStoreId}?mt=8&ls=1`;
86+
}
7687
}
7788
$injector.register("previewQrCodeService", PreviewQrCodeService);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { PubnubKeys } from "./preview-app-constants";
2+
3+
export class PreviewSchemaService implements IPreviewSchemaService {
4+
private previewSchemas: IDictionary<IPreviewSchemaData> = {
5+
"nsplay": {
6+
name: "nsplay",
7+
scannerAppId: "org.nativescript.play",
8+
scannerAppStoreId: "1263543946",
9+
previewAppId: "org.nativescript.preview",
10+
previewAppStoreId: "1264484702",
11+
msvKey: "cli",
12+
publishKey: PubnubKeys.PUBLISH_KEY,
13+
subscribeKey: PubnubKeys.SUBSCRIBE_KEY,
14+
default: true
15+
},
16+
"ksplay": {
17+
name: "ksplay",
18+
scannerAppId: "com.kinvey.scanner",
19+
scannerAppStoreId: "1263543946",
20+
previewAppId: "com.kinvey.preview",
21+
previewAppStoreId: "1264484702",
22+
msvKey: "kinveyStudio",
23+
publishKey: PubnubKeys.PUBLISH_KEY,
24+
subscribeKey: PubnubKeys.SUBSCRIBE_KEY
25+
}
26+
};
27+
28+
constructor(private $errors: IErrors,
29+
private $projectDataService: IProjectDataService) { }
30+
31+
public getSchemaData(projectDir: string): IPreviewSchemaData {
32+
let schemaName = this.getSchemaNameFromProject(projectDir);
33+
if (!schemaName) {
34+
schemaName = _.findKey(this.previewSchemas, previewSchema => previewSchema.default);
35+
}
36+
37+
const result = this.previewSchemas[schemaName];
38+
if (!result) {
39+
this.$errors.failWithoutHelp(`Invalid schema. The valid schemas are ${_.keys(this.previewSchemas)}.`);
40+
}
41+
42+
return result;
43+
}
44+
45+
private getSchemaNameFromProject(projectDir: string): string {
46+
try {
47+
const projectData = this.$projectDataService.getProjectData(projectDir);
48+
return projectData.previewAppSchema;
49+
} catch (err) { /* ignore the error */ }
50+
51+
return null;
52+
}
53+
}
54+
$injector.register("previewSchemaService", PreviewSchemaService);

lib/services/livesync/playground/preview-sdk-service.ts

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { MessagingService, Config, Device, DeviceConnectedMessage, SdkCallbacks, ConnectedDevices, FilesPayload } from "nativescript-preview-sdk";
2-
import { PubnubKeys } from "./preview-app-constants";
32
import { EventEmitter } from "events";
43
const pako = require("pako");
54

@@ -13,24 +12,20 @@ export class PreviewSdkService extends EventEmitter implements IPreviewSdkServic
1312
private $logger: ILogger,
1413
private $previewDevicesService: IPreviewDevicesService,
1514
private $previewAppLogProvider: IPreviewAppLogProvider,
16-
private $projectDataService: IProjectDataService) {
15+
private $previewSchemaService: IPreviewSchemaService) {
1716
super();
1817
}
1918

2019
public getQrCodeUrl(options: IGetQrCodeUrlOptions): string {
2120
const { projectDir, useHotModuleReload } = options;
22-
const projectData = this.$projectDataService.getProjectData(projectDir);
23-
const schema = projectData.previewAppSchema || "nsplay";
24-
// TODO: Use the correct keys for the schema
25-
const publishKey = PubnubKeys.PUBLISH_KEY;
26-
const subscribeKey = PubnubKeys.SUBSCRIBE_KEY;
21+
const schema = this.$previewSchemaService.getSchemaData(projectDir);
2722
const hmrValue = useHotModuleReload ? "1" : "0";
28-
const result = `${schema}://boot?instanceId=${this.instanceId}&pKey=${publishKey}&sKey=${subscribeKey}&template=play-ng&hmr=${hmrValue}`;
23+
const result = `${schema.name}://boot?instanceId=${this.instanceId}&pKey=${schema.publishKey}&sKey=${schema.subscribeKey}&template=play-ng&hmr=${hmrValue}`;
2924
return result;
3025
}
3126

32-
public async initialize(getInitialFiles: (device: Device) => Promise<FilesPayload>): Promise<void> {
33-
const initConfig = this.getInitConfig(getInitialFiles);
27+
public async initialize(projectDir: string, getInitialFiles: (device: Device) => Promise<FilesPayload>): Promise<void> {
28+
const initConfig = this.getInitConfig(projectDir, getInitialFiles);
3429
this.messagingService = new MessagingService();
3530
this.instanceId = await this.messagingService.initialize(initConfig);
3631
}
@@ -51,15 +46,18 @@ export class PreviewSdkService extends EventEmitter implements IPreviewSdkServic
5146
this.messagingService.stop();
5247
}
5348

54-
private getInitConfig(getInitialFiles: (device: Device) => Promise<FilesPayload>): Config {
49+
private getInitConfig(projectDir: string, getInitialFiles: (device: Device) => Promise<FilesPayload>): Config {
50+
const schema = this.$previewSchemaService.getSchemaData(projectDir);
51+
5552
return {
56-
pubnubPublishKey: PubnubKeys.PUBLISH_KEY,
57-
pubnubSubscribeKey: PubnubKeys.SUBSCRIBE_KEY,
58-
msvKey: "cli",
53+
pubnubPublishKey: schema.publishKey,
54+
pubnubSubscribeKey: schema.subscribeKey,
55+
msvKey: schema.msvKey,
5956
msvEnv: this.$config.PREVIEW_APP_ENVIRONMENT,
60-
showLoadingPage: false,
6157
callbacks: this.getCallbacks(),
62-
getInitialFiles
58+
getInitialFiles,
59+
previewAppStoreId: schema.previewAppStoreId,
60+
previewAppGooglePlayId: schema.previewAppId
6361
};
6462
}
6563

npm-shrinkwrap.json

Lines changed: 4 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"mute-stream": "0.0.5",
5959
"nativescript-dev-xcode": "0.1.0",
6060
"nativescript-doctor": "1.9.2",
61-
"nativescript-preview-sdk": "0.3.3",
61+
"nativescript-preview-sdk": "0.3.4",
6262
"open": "0.0.5",
6363
"ora": "2.0.0",
6464
"osenv": "0.1.3",

test/services/playground/preview-app-livesync-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class PreviewSdkServiceMock extends EventEmitter implements IPreviewSdkService {
7373
return "my_cool_qr_code_url";
7474
}
7575

76-
public initialize(getInitialFiles: (device: Device) => Promise<FilesPayload>) {
76+
public initialize(projectDir: string, getInitialFiles: (device: Device) => Promise<FilesPayload>) {
7777
this.getInitialFiles = async (device) => {
7878
const filesPayload = await getInitialFiles(device);
7979
initialFiles.push(...filesPayload.files);
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { Yok } from "../../../lib/common/yok";
2+
import { PreviewSchemaService } from "../../../lib/services/livesync/playground/preview-schema-service";
3+
import { PubnubKeys } from "../../../lib/services/livesync/playground/preview-app-constants";
4+
import { assert } from "chai";
5+
6+
function createTestInjector(): IInjector {
7+
const injector = new Yok();
8+
injector.register("previewSchemaService", PreviewSchemaService);
9+
injector.register("projectDataService", () => ({}));
10+
injector.register("errors", () => ({}));
11+
12+
return injector;
13+
}
14+
15+
const nsPlaySchema = {
16+
name: 'nsplay',
17+
scannerAppId: 'org.nativescript.play',
18+
scannerAppStoreId: '1263543946',
19+
previewAppId: 'org.nativescript.preview',
20+
previewAppStoreId: '1264484702',
21+
msvKey: 'cli',
22+
publishKey: PubnubKeys.PUBLISH_KEY,
23+
subscribeKey: PubnubKeys.SUBSCRIBE_KEY,
24+
default: true
25+
};
26+
27+
const ksPlaySchema = {
28+
name: 'ksplay',
29+
scannerAppId: 'com.kinvey.scanner',
30+
scannerAppStoreId: '1263543946',
31+
previewAppId: 'com.kinvey.preview',
32+
previewAppStoreId: '1264484702',
33+
msvKey: 'kinveyStudio',
34+
publishKey: PubnubKeys.PUBLISH_KEY,
35+
subscribeKey: PubnubKeys.SUBSCRIBE_KEY
36+
};
37+
38+
describe("PreviewSchemaService", () => {
39+
let injector: IInjector;
40+
let previewSchemaService: IPreviewSchemaService;
41+
42+
beforeEach(() => {
43+
injector = createTestInjector();
44+
previewSchemaService = injector.resolve("previewSchemaService");
45+
});
46+
47+
const testCases = [
48+
{
49+
name: "should return default nsplay schema when no previewAppSchema in nsconfig",
50+
previewAppSchema: <any>null,
51+
expectedSchema: nsPlaySchema
52+
},
53+
{
54+
name: "should return nsplay schema when { 'previewAppSchema': 'nsplay' } in nsconfig",
55+
previewAppSchema: "nsplay",
56+
expectedSchema: nsPlaySchema
57+
},
58+
{
59+
name: "should return ksplay schema when { 'previewAppSchema': 'ksplay' } in nsconfig",
60+
previewAppSchema: "ksplay",
61+
expectedSchema: ksPlaySchema
62+
},
63+
{
64+
name: "should throw an error when invalid previewAppSchema is specified in nsconfig",
65+
previewAppSchema: "someInvalidSchema",
66+
expectedToThrow: true
67+
}
68+
];
69+
70+
_.each(testCases, testCase => {
71+
it(`${testCase.name}`, () => {
72+
const projectDataService = injector.resolve("projectDataService");
73+
projectDataService.getProjectData = () => ({ previewAppSchema: testCase.previewAppSchema });
74+
75+
let actualError = null;
76+
if (testCase.expectedToThrow) {
77+
const errors = injector.resolve("errors");
78+
errors.failWithoutHelp = (err: string) => actualError = err;
79+
}
80+
81+
const schemaData = previewSchemaService.getSchemaData("someTestProjectDir");
82+
83+
assert.deepEqual(schemaData, testCase.expectedSchema);
84+
if (testCase.expectedToThrow) {
85+
assert.isNotNull(actualError);
86+
}
87+
});
88+
});
89+
});

0 commit comments

Comments
 (0)