Skip to content

Commit

Permalink
Merge pull request #4492 from NativeScript/fatme/kinvey-schema
Browse files Browse the repository at this point in the history
feat(kinvey): provide correct data to preview-sdk based on the schema
  • Loading branch information
rosen-vladimirov authored Apr 2, 2019
2 parents 882ca60 + ad2a4df commit 27ca961
Show file tree
Hide file tree
Showing 13 changed files with 206 additions and 47 deletions.
1 change: 1 addition & 0 deletions lib/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ $injector.require("previewAppLiveSyncService", "./services/livesync/playground/p
$injector.require("previewAppLogProvider", "./services/livesync/playground/preview-app-log-provider");
$injector.require("previewAppPluginsService", "./services/livesync/playground/preview-app-plugins-service");
$injector.require("previewSdkService", "./services/livesync/playground/preview-sdk-service");
$injector.require("previewSchemaService", "./services/livesync/playground/preview-schema-service");
$injector.requirePublicClass("previewDevicesService", "./services/livesync/playground/devices/preview-devices-service");
$injector.requirePublic("previewQrCodeService", "./services/livesync/playground/preview-qr-code-service");
$injector.requirePublic("sysInfo", "./sys-info");
Expand Down
20 changes: 18 additions & 2 deletions lib/definitions/preview-app-livesync.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ declare global {

interface IPreviewSdkService extends EventEmitter {
getQrCodeUrl(options: IGetQrCodeUrlOptions): string;
initialize(getInitialFiles: (device: Device) => Promise<FilesPayload>): void;
initialize(projectDir: string, getInitialFiles: (device: Device) => Promise<FilesPayload>): void;
applyChanges(filesPayload: FilesPayload): Promise<void>;
stop(): void;
}
Expand All @@ -45,7 +45,7 @@ declare global {
printLiveSyncQrCode(options: IPrintLiveSyncOptions): Promise<void>;
}

interface IPlaygroundAppQrCodeOptions {
interface IPlaygroundAppQrCodeOptions extends IProjectDir {
platform?: string;
}

Expand All @@ -64,4 +64,20 @@ declare global {
getDevicesForPlatform(platform: string): Device[];
getPluginsUsageWarnings(data: IPreviewAppLiveSyncData, device: Device): string[];
}

interface IPreviewSchemaService {
getSchemaData(projectDir: string): IPreviewSchemaData;
}

interface IPreviewSchemaData {
name: string;
scannerAppId: string;
scannerAppStoreId: string;
previewAppId: string;
previewAppStoreId: string;
msvKey: string;
publishKey: string;
subscribeKey: string;
default?: boolean;
}
}
5 changes: 0 additions & 5 deletions lib/services/livesync/playground/preview-app-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ export class PubnubKeys {
public static SUBSCRIBE_KEY = "sub-c-3dad1ebe-aaa3-11e8-8027-363023237e0b";
}

export class PlaygroundStoreUrls {
public static GOOGLE_PLAY_URL = "https://play.google.com/store/apps/details?id=org.nativescript.play";
public static APP_STORE_URL = "https://itunes.apple.com/us/app/nativescript-playground/id1263543946?mt=8&ls=1";
}

export class PluginComparisonMessages {
public static PLUGIN_NOT_INCLUDED_IN_PREVIEW_APP = "Plugin %s is not included in preview app on device %s and will not work.";
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.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class PreviewAppLiveSyncService extends EventEmitter implements IPreviewA

@performanceLog()
public async initialize(data: IPreviewAppLiveSyncData): Promise<void> {
await this.$previewSdkService.initialize(async (device: Device) => {
await this.$previewSdkService.initialize(data.projectDir, async (device: Device) => {
try {
if (!device) {
this.$errors.failWithoutHelp("Sending initial preview files without a specified device is not supported.");
Expand Down
21 changes: 16 additions & 5 deletions lib/services/livesync/playground/preview-qr-code-service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as util from "util";
import { EOL } from "os";
import { PlaygroundStoreUrls } from "./preview-app-constants";
import { exported } from "../../../common/decorators";

export class PreviewQrCodeService implements IPreviewQrCodeService {
Expand All @@ -10,20 +9,22 @@ export class PreviewQrCodeService implements IPreviewQrCodeService {
private $logger: ILogger,
private $mobileHelper: Mobile.IMobileHelper,
private $previewSdkService: IPreviewSdkService,
private $previewSchemaService: IPreviewSchemaService,
private $qrCodeTerminalService: IQrCodeTerminalService,
private $qr: IQrCodeGenerator
) { }

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

if (!options || !options.platform || this.$mobileHelper.isAndroidPlatform(options.platform)) {
result.android = await this.getLiveSyncQrCode(PlaygroundStoreUrls.GOOGLE_PLAY_URL);
result.android = await this.getLiveSyncQrCode(this.getGooglePlayUrl(projectDir));
}

if (!options || !options.platform || this.$mobileHelper.isiOSPlatform(options.platform)) {
result.ios = await this.getLiveSyncQrCode(PlaygroundStoreUrls.APP_STORE_URL);
result.ios = await this.getLiveSyncQrCode(this.getAppStoreUrl(projectDir));
}

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

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

return url;
}

private getGooglePlayUrl(projectDir: string): string {
const schema = this.$previewSchemaService.getSchemaData(projectDir);
return `https://play.google.com/store/apps/details?id=${schema.scannerAppId}`;
}

private getAppStoreUrl(projectDir: string): string {
const schema = this.$previewSchemaService.getSchemaData(projectDir);
return `https://itunes.apple.com/us/app/nativescript-playground/id${schema.scannerAppStoreId}?mt=8&ls=1`;
}
}
$injector.register("previewQrCodeService", PreviewQrCodeService);
54 changes: 54 additions & 0 deletions lib/services/livesync/playground/preview-schema-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { PubnubKeys } from "./preview-app-constants";

export class PreviewSchemaService implements IPreviewSchemaService {
private previewSchemas: IDictionary<IPreviewSchemaData> = {
"nsplay": {
name: "nsplay",
scannerAppId: "org.nativescript.play",
scannerAppStoreId: "1263543946",
previewAppId: "org.nativescript.preview",
previewAppStoreId: "1264484702",
msvKey: "cli",
publishKey: PubnubKeys.PUBLISH_KEY,
subscribeKey: PubnubKeys.SUBSCRIBE_KEY,
default: true
},
"ksplay": {
name: "ksplay",
scannerAppId: "com.kinvey.scanner",
scannerAppStoreId: "1263543946",
previewAppId: "com.kinvey.preview",
previewAppStoreId: "1264484702",
msvKey: "kinveyStudio",
publishKey: PubnubKeys.PUBLISH_KEY,
subscribeKey: PubnubKeys.SUBSCRIBE_KEY
}
};

constructor(private $errors: IErrors,
private $projectDataService: IProjectDataService) { }

public getSchemaData(projectDir: string): IPreviewSchemaData {
let schemaName = this.getSchemaNameFromProject(projectDir);
if (!schemaName) {
schemaName = _.findKey(this.previewSchemas, previewSchema => previewSchema.default);
}

const result = this.previewSchemas[schemaName];
if (!result) {
this.$errors.failWithoutHelp(`Invalid schema. The valid schemas are ${_.keys(this.previewSchemas)}.`);
}

return result;
}

private getSchemaNameFromProject(projectDir: string): string {
try {
const projectData = this.$projectDataService.getProjectData(projectDir);
return projectData.previewAppSchema;
} catch (err) { /* ignore the error */ }

return null;
}
}
$injector.register("previewSchemaService", PreviewSchemaService);
30 changes: 14 additions & 16 deletions lib/services/livesync/playground/preview-sdk-service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { MessagingService, Config, Device, DeviceConnectedMessage, SdkCallbacks, ConnectedDevices, FilesPayload } from "nativescript-preview-sdk";
import { PubnubKeys } from "./preview-app-constants";
import { EventEmitter } from "events";
const pako = require("pako");

Expand All @@ -13,24 +12,20 @@ export class PreviewSdkService extends EventEmitter implements IPreviewSdkServic
private $logger: ILogger,
private $previewDevicesService: IPreviewDevicesService,
private $previewAppLogProvider: IPreviewAppLogProvider,
private $projectDataService: IProjectDataService) {
private $previewSchemaService: IPreviewSchemaService) {
super();
}

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

public async initialize(getInitialFiles: (device: Device) => Promise<FilesPayload>): Promise<void> {
const initConfig = this.getInitConfig(getInitialFiles);
public async initialize(projectDir: string, getInitialFiles: (device: Device) => Promise<FilesPayload>): Promise<void> {
const initConfig = this.getInitConfig(projectDir, getInitialFiles);
this.messagingService = new MessagingService();
this.instanceId = await this.messagingService.initialize(initConfig);
}
Expand All @@ -51,15 +46,18 @@ export class PreviewSdkService extends EventEmitter implements IPreviewSdkServic
this.messagingService.stop();
}

private getInitConfig(getInitialFiles: (device: Device) => Promise<FilesPayload>): Config {
private getInitConfig(projectDir: string, getInitialFiles: (device: Device) => Promise<FilesPayload>): Config {
const schema = this.$previewSchemaService.getSchemaData(projectDir);

return {
pubnubPublishKey: PubnubKeys.PUBLISH_KEY,
pubnubSubscribeKey: PubnubKeys.SUBSCRIBE_KEY,
msvKey: "cli",
pubnubPublishKey: schema.publishKey,
pubnubSubscribeKey: schema.subscribeKey,
msvKey: schema.msvKey,
msvEnv: this.$config.PREVIEW_APP_ENVIRONMENT,
showLoadingPage: false,
callbacks: this.getCallbacks(),
getInitialFiles
getInitialFiles,
previewAppStoreId: schema.previewAppStoreId,
previewAppGooglePlayId: schema.previewAppId
};
}

Expand Down
16 changes: 4 additions & 12 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"mute-stream": "0.0.5",
"nativescript-dev-xcode": "0.1.0",
"nativescript-doctor": "1.9.2",
"nativescript-preview-sdk": "0.3.3",
"nativescript-preview-sdk": "0.3.4",
"open": "0.0.5",
"ora": "2.0.0",
"osenv": "0.1.3",
Expand Down
2 changes: 1 addition & 1 deletion test/services/playground/preview-app-livesync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class PreviewSdkServiceMock extends EventEmitter implements IPreviewSdkService {
return "my_cool_qr_code_url";
}

public initialize(getInitialFiles: (device: Device) => Promise<FilesPayload>) {
public initialize(projectDir: string, getInitialFiles: (device: Device) => Promise<FilesPayload>) {
this.getInitialFiles = async (device) => {
const filesPayload = await getInitialFiles(device);
initialFiles.push(...filesPayload.files);
Expand Down
89 changes: 89 additions & 0 deletions test/services/playground/preview-schema-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { Yok } from "../../../lib/common/yok";
import { PreviewSchemaService } from "../../../lib/services/livesync/playground/preview-schema-service";
import { PubnubKeys } from "../../../lib/services/livesync/playground/preview-app-constants";
import { assert } from "chai";

function createTestInjector(): IInjector {
const injector = new Yok();
injector.register("previewSchemaService", PreviewSchemaService);
injector.register("projectDataService", () => ({}));
injector.register("errors", () => ({}));

return injector;
}

const nsPlaySchema = {
name: 'nsplay',
scannerAppId: 'org.nativescript.play',
scannerAppStoreId: '1263543946',
previewAppId: 'org.nativescript.preview',
previewAppStoreId: '1264484702',
msvKey: 'cli',
publishKey: PubnubKeys.PUBLISH_KEY,
subscribeKey: PubnubKeys.SUBSCRIBE_KEY,
default: true
};

const ksPlaySchema = {
name: 'ksplay',
scannerAppId: 'com.kinvey.scanner',
scannerAppStoreId: '1263543946',
previewAppId: 'com.kinvey.preview',
previewAppStoreId: '1264484702',
msvKey: 'kinveyStudio',
publishKey: PubnubKeys.PUBLISH_KEY,
subscribeKey: PubnubKeys.SUBSCRIBE_KEY
};

describe("PreviewSchemaService", () => {
let injector: IInjector;
let previewSchemaService: IPreviewSchemaService;

beforeEach(() => {
injector = createTestInjector();
previewSchemaService = injector.resolve("previewSchemaService");
});

const testCases = [
{
name: "should return default nsplay schema when no previewAppSchema in nsconfig",
previewAppSchema: <any>null,
expectedSchema: nsPlaySchema
},
{
name: "should return nsplay schema when { 'previewAppSchema': 'nsplay' } in nsconfig",
previewAppSchema: "nsplay",
expectedSchema: nsPlaySchema
},
{
name: "should return ksplay schema when { 'previewAppSchema': 'ksplay' } in nsconfig",
previewAppSchema: "ksplay",
expectedSchema: ksPlaySchema
},
{
name: "should throw an error when invalid previewAppSchema is specified in nsconfig",
previewAppSchema: "someInvalidSchema",
expectedToThrow: true
}
];

_.each(testCases, testCase => {
it(`${testCase.name}`, () => {
const projectDataService = injector.resolve("projectDataService");
projectDataService.getProjectData = () => ({ previewAppSchema: testCase.previewAppSchema });

let actualError = null;
if (testCase.expectedToThrow) {
const errors = injector.resolve("errors");
errors.failWithoutHelp = (err: string) => actualError = err;
}

const schemaData = previewSchemaService.getSchemaData("someTestProjectDir");

assert.deepEqual(schemaData, testCase.expectedSchema);
if (testCase.expectedToThrow) {
assert.isNotNull(actualError);
}
});
});
});
Loading

0 comments on commit 27ca961

Please sign in to comment.