Skip to content

Commit

Permalink
feat: i18n sync
Browse files Browse the repository at this point in the history
  • Loading branch information
janvennemann committed Nov 20, 2020
1 parent 1b6bbda commit c04e25b
Show file tree
Hide file tree
Showing 33 changed files with 1,091 additions and 230 deletions.
8 changes: 8 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ module.exports = {
'plugin:@typescript-eslint/recommended',
]
},
{
files: ['*.spec.ts'],
rules: {
'@typescript-eslint/ban-ts-comment': ['error', {
'ts-ignore': 'allow-with-description'
}]
}
},
{
files: ['*.js'],
extends: 'axway/env-node',
Expand Down
3 changes: 1 addition & 2 deletions packages/appcd-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ let server: LiveViewServer | null;

export function activate(config: AppcdConfig): void {
server = new LiveViewServer({
port: config.liveview.port,
daemonized: true
port: config.liveview.port
});
server.start();

Expand Down
17 changes: 4 additions & 13 deletions packages/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ interface ServerAddress {
}

interface ClientOptions extends ServerAddress {
workspace: string,
daemon?: ServerAddress
workspace: string
}

interface TransferInfo {
Expand All @@ -34,12 +33,7 @@ export default class Client {
this.baseDir = Ti.Platform.osname === 'android'
? Ti.Filesystem.applicationDataDirectory
: Ti.Filesystem.applicationSupportDirectory;
if (options.daemon) {
const { host: daemonHost, port: daemonPort } = options.daemon;
this.assetServeEndpoint = `http://${daemonHost}:${daemonPort}/liveview/latest/workspace/${workspace}/serve`;
} else {
this.assetServeEndpoint = `http://${host}:${port}/workspace/${workspace}/serve`;
}
this.assetServeEndpoint = `http://${host}:${port}/workspace/${workspace}/serve`;

this.socket = io(`http://${host}:${port}/workspace/${workspace}`);

Expand Down Expand Up @@ -116,14 +110,11 @@ export default class Client {
reject(e);
};
client.onload = () => {
const content = Ti.Utils.base64decode(client.responseData);
targetFile.write(content);
targetFile.write(client.responseData);
resolve();
};
client.send(JSON.stringify({
data: {
file: from
}
file: from
}));
});
}
Expand Down
14 changes: 14 additions & 0 deletions packages/liveview/bootstrap/liveview.bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,17 @@ const client = new Client({
port,
workspace: '__WORKSPACE__'
});

try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const i18n = require('__i18n__.json');
global.L = (key: string, hint?: string): string => {
const lang = i18n[Ti.Locale.currentLanguage];
if (!lang) {
return hint || key;
}
return lang[key] || hint || key;
};
} catch (e) {
// No synced i18n data, do nothing
}
52 changes: 31 additions & 21 deletions packages/liveview/src/hook.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { LiveViewServer, WorkspaceOptions, WorkspaceType } from '@liveview/server';
import {
LiveViewServer,
Workspace,
WorkspaceOptions,
WorkspaceType
} from '@liveview/server';
import { appcd } from '@liveview/shared-utils';
import fs from 'fs-extra';
import os from 'os';
Expand Down Expand Up @@ -47,7 +52,7 @@ export function init(logger: any, config: any, cli: any): void {
};
await fs.ensureDir(builder.liveView.assetsPath);

// write liveview.bootstrap.js
// resolve host and port
let host;
let port;
if (useDaemon) {
Expand All @@ -58,23 +63,9 @@ export function init(logger: any, config: any, cli: any): void {
host = cli.argv['liveview-ip'] || resolveHost();
port = cli.argv['liveview-port'] || 8323;
}
const templateFile = path.resolve(__dirname, 'liveview.bootstrap.js');
let bootstrapContent = await fs.readFile(templateFile, 'utf-8');
bootstrapContent = bootstrapContent
.replace('__HOST__', host)
.replace('__PORT__', port)
.replace('__WORKSPACE__', builder.tiapp.name);
const bootstrapPath = path.join(builder.liveView.assetsPath, 'liveview.bootstrap.js');
await fs.writeFile(
bootstrapPath,
bootstrapContent
);
builder.liveView.files.push({
src: bootstrapPath,
relativePath: 'liveview.bootstrap.js'
});

const workspace: WorkspaceOptions = {
// start liveview server
const options: WorkspaceOptions = {
name: builder.tiapp.name,
path: builder.projectDir,
type: determineProjectType(builder),
Expand All @@ -84,19 +75,38 @@ export function init(logger: any, config: any, cli: any): void {
// @todo: determine per platform
ios: builder.minIosVersion
}
}
},
hmr: false
};
let workspace: Workspace;
if (useDaemon) {
await appcd.post('/liveview/latest/workspace', workspace);
workspace = await appcd.post('/liveview/latest/workspace', options);
} else {
const server = new LiveViewServer({
host,
port
});
server.addWorkspace(workspace);
workspace = await server.addWorkspace(options);
await server.start();
}

// write liveview.bootstrap.js
const templateFile = path.resolve(__dirname, 'liveview.bootstrap.js');
let bootstrapContent = await fs.readFile(templateFile, 'utf-8');
bootstrapContent = bootstrapContent
.replace('__HOST__', host)
.replace('__PORT__', port)
.replace('__WORKSPACE__', workspace.slug);
const bootstrapPath = path.join(builder.liveView.assetsPath, 'liveview.bootstrap.js');
await fs.writeFile(
bootstrapPath,
bootstrapContent
);
builder.liveView.files.push({
src: bootstrapPath,
relativePath: 'liveview.bootstrap.js'
});

done();
});

Expand Down
1 change: 1 addition & 0 deletions packages/server/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { compilerOptions } = require('./tsconfig.json');

module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
prefix: '<rootDir>'
})
Expand Down
14 changes: 13 additions & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@
],
"license": "Apache-2.0",
"dependencies": {
"@sindresorhus/slugify": "^1.1.0",
"@types/koa": "^2.11.6",
"chokidar": "^3.4.3",
"fast-xml-parser": "^3.17.4",
"fs-extra": "^9.0.1",
"koa": "^2.13.0",
"koa-bodyparser": "^4.3.0",
"koa-route": "^3.2.0",
"koa-send": "^5.0.1",
"lodash.isequal": "^4.5.0",
"node-titanium-sdk": "^5.1.2",
"socket.io": "^2.3.0",
Expand All @@ -22,6 +29,11 @@
"devDependencies": {
"@types/fs-extra": "^9.0.2",
"@types/glob-to-regexp": "^0.4.0",
"@types/lodash.isequal": "^4.5.5"
"@types/koa": "^2.11.6",
"@types/koa-bodyparser": "^4.3.0",
"@types/koa-route": "^3.2.4",
"@types/koa-send": "^4.1.2",
"@types/lodash.isequal": "^4.5.5",
"axios": "^0.21.0"
}
}
4 changes: 2 additions & 2 deletions packages/server/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ export default class Client {

}

sendManifest(changes: TransferInfo[], removals: Set<string>): void {
sendManifest(changes: TransferInfo[], removals: string[]): void {
this.socket.emit('manifest', {
changes,
removals: Array.from(removals)
removals
});
}
}
45 changes: 29 additions & 16 deletions packages/server/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import slugify from '@sindresorhus/slugify';
import http from 'http';
import Koa from 'koa';
import bodyParser from 'koa-bodyparser';
import route from 'koa-route';
import send from 'koa-send';
import { Socket } from 'net';
import io from 'socket.io';
import { URL } from 'url';

import Client from './client';
import { DeviceInfo } from './index';
Expand All @@ -11,15 +15,13 @@ import { getWorkspaceName, workspacePattern } from './utils';
export interface LiveViewOptions {
host?: string
port?: number
daemonized?: boolean
}

export class LiveViewServer {
public workspaces: Map<string, Workspace>;

private server!: http.Server;
private socketServer!: io.Server;
private connections = new Set<Socket>();
public workspaces: Map<string, Workspace>
private server!: http.Server
private socketServer!: io.Server
private connections = new Set<Socket>()

constructor(private options: LiveViewOptions = {}) {
this.workspaces = new Map();
Expand All @@ -31,14 +33,23 @@ export class LiveViewServer {
}

private async createHttpServer(): Promise<http.Server> {
const { host = '0.0.0.0', port = 3000 } = this.options;
const server = this.server = http.createServer((req, res) => {
if (this.options.daemonized) {
return;
const { host = '0.0.0.0', port = 8323 } = this.options;

const app = new Koa();
app.use(bodyParser());
app.use(route.post('/workspace/:name/serve', async (ctx, name) => {
const workspace = this.workspaces.get(name);
if (!workspace) {
return ctx.throw(404, 'Worksapce not found');
}
const data = ctx.request.body;
if (!data.file) {
return ctx.throw(400);
}
await send(ctx, data.file, { root: workspace.path });
}));

const url = new URL(req.url!);
});
const server = this.server = http.createServer(app.callback());
server.on('connection', socket => {
this.connections.add(socket);
socket.once('close', () => {
Expand Down Expand Up @@ -112,12 +123,14 @@ export class LiveViewServer {
this.workspaces.clear();
}

async addWorkspace(options: WorkspaceOptions): Promise<void> {
const existingWorkspace = this.workspaces.get(options.name);
async addWorkspace(options: WorkspaceOptions): Promise<Workspace> {
const slug = slugify(options.name);
const existingWorkspace = this.workspaces.get(slug);
if (existingWorkspace) {
await existingWorkspace.close();
}
const workspace = new Workspace(options);
this.workspaces.set(workspace.name, workspace);
this.workspaces.set(workspace.slug, workspace);
return workspace;
}
}
63 changes: 63 additions & 0 deletions packages/server/src/transformers/assets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import fs from 'fs-extra';
import jsanalyze = require('node-titanium-sdk/lib/jsanalyze');
import path from 'path';

import { AbstractTransformer, TransformerOptions } from "./base";
import { TranspileOptions } from '../workspace';
import { TransferInfo } from "..";

export interface AssetsTransformerOptions extends TransformerOptions {
transpile: TranspileOptions
}

let _jsAnalyze: typeof jsanalyze;

/**
* Transformer for app assets under the project's `Resources` directory.
*
* Currently only `.js` files will be transformed if transpilation is enabled.
*/
export class AssetsTransformer extends AbstractTransformer {
private transpile: TranspileOptions

constructor(options: AssetsTransformerOptions) {
super(options);

this.transpile = options.transpile;
if (this.transpile.enabled) {
_jsAnalyze = require('node-titanium-sdk/lib/jsanalyze');
}
}

async transform(changes: string[]): Promise<TransferInfo[]> {
const files: TransferInfo[] = [];
for (const file of changes) {
const relativePath = path.relative(this.basePath, file);
const ext = path.extname(file);
let sourceFile = file;

if (ext === '.js' && this.transpile.enabled) {
const filename = path.basename(file);
const transpiled = _jsAnalyze.analyzeJsFile(file, {
filename: filename,
minify: false,
transpile: true,
targets: this.transpile.targets,
sourceMap: false
});
if (transpiled.contents) {
const outputPath = path.join(this.intermediateBuildDir, relativePath);
fs.outputFileSync(outputPath, transpiled.contents);
sourceFile = outputPath;
}
}

files.push({
from: path.relative(this.workspacePath, sourceFile),
to: path.relative(this.basePath, file)
});
}

return files;
}
}

0 comments on commit c04e25b

Please sign in to comment.