1
0
Code Issues Pull Requests Packages Projects Releases Wiki Activity GitHub Gitee
This commit is contained in:
tdzl2003 2016-02-14 00:04:42 +08:00
commit 74396f8426
10 changed files with 382 additions and 0 deletions

11
index.js Normal file
View File

@ -0,0 +1,11 @@
/**
* Created by tdzl2003 on 2/6/16.
*/
if (__DEV__){
if (global.__fbBatchedBridge) {
require('fbjs/lib/warning')('Should require pushy before react-native to do hook stuff!');
}
}
require('./lib/hooks');

8
lib/hooks.js Normal file
View File

@ -0,0 +1,8 @@
/**
* Created by tdzl2003 on 2/6/16.
*/
// Hook resolvedAssetSource
__d('resolveAssetSource', function(_1, _2, module, _3) {
module.exports = require('./resolveAssetSource');
});

146
lib/resolveAssetSource.js Normal file
View File

@ -0,0 +1,146 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule resolveAssetSource
* @flow
*
* Resolves an asset into a `source` for `Image`.
*
* Hooked by @tdzl2003 for react-native-pushy
*/
'use strict';
var AssetRegistry = require('react-native/Libraries/Image/AssetRegistry');
var PixelRatio = require('react-native/Libraries/Utilities/PixelRatio');
var Platform = require('react-native/Libraries/Utilities/Platform');
var NativeModules = require('react-native/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js');
var SourceCode = NativeModules.SourceCode;
var _serverURL, _offlinePath;
function getDevServerURL() {
if (_serverURL === undefined) {
var scriptURL = SourceCode.scriptURL;
var match = scriptURL && scriptURL.match(/^https?:\/\/.*?\//);
if (match) {
// Bundle was loaded from network
_serverURL = match[0];
} else {
// Bundle was loaded from file
_serverURL = null;
}
}
return _serverURL;
}
function getOfflinePath() {
if (_offlinePath === undefined) {
var scriptURL = SourceCode.scriptURL;
var match = scriptURL && scriptURL.match(/^file:\/\/(\/.*\/)/);
if (match) {
_offlinePath = match[1];
} else {
_offlinePath = '';
}
}
return _offlinePath;
}
/**
* Returns the path at which the asset can be found in the archive
*/
function getPathInArchive(asset) {
if (Platform.OS === 'android') {
var assetDir = getBasePath(asset);
// E.g. 'assets_awesomemodule_icon'
// The Android resource system picks the correct scale.
return (assetDir + '/' + asset.name)
.toLowerCase()
.replace(/\//g, '_') // Encode folder structure in file name
.replace(/([^a-z0-9_])/g, '') // Remove illegal chars
.replace(/^assets_/, ''); // Remove "assets_" prefix
} else {
// E.g. 'assets/AwesomeModule/icon@2x.png'
return getOfflinePath() + getScaledAssetPath(asset);
}
}
/**
* Returns an absolute URL which can be used to fetch the asset
* from the devserver
*/
function getPathOnDevserver(devServerUrl, asset) {
return devServerUrl + getScaledAssetPath(asset) + '?platform=' + Platform.OS +
'&hash=' + asset.hash;
}
/**
* Returns a path like 'assets/AwesomeModule'
*/
function getBasePath(asset) {
// TODO(frantic): currently httpServerLocation is used both as
// path in http URL and path within IPA. Should we have zipArchiveLocation?
var path = asset.httpServerLocation;
if (path[0] === '/') {
path = path.substr(1);
}
return path;
}
/**
* Returns a path like 'assets/AwesomeModule/icon@2x.png'
*/
function getScaledAssetPath(asset) {
var scale = pickScale(asset.scales, PixelRatio.get());
var scaleSuffix = scale === 1 ? '' : '@' + scale + 'x';
var assetDir = getBasePath(asset);
return assetDir + '/' + asset.name + scaleSuffix + '.' + asset.type;
}
function pickScale(scales, deviceScale) {
// Packager guarantees that `scales` array is sorted
for (var i = 0; i < scales.length; i++) {
if (scales[i] >= deviceScale) {
return scales[i];
}
}
// If nothing matches, device scale is larger than any available
// scales, so we return the biggest one. Unless the array is empty,
// in which case we default to 1
return scales[scales.length - 1] || 1;
}
function resolveAssetSource(source){
if (typeof source === 'object') {
return source;
}
var asset = AssetRegistry.getAssetByID(source);
if (asset) {
return assetToImageSource(asset);
}
return null;
}
function assetToImageSource(asset){
var devServerURL = getDevServerURL();
return {
__packager_asset: true,
width: asset.width,
height: asset.height,
uri: devServerURL ? getPathOnDevserver(devServerURL, asset) : getPathInArchive(asset),
scale: pickScale(asset.scales, PixelRatio.get()),
};
}
module.exports = resolveAssetSource;
module.exports.pickScale = pickScale;

55
local-cli/api.js Normal file
View File

@ -0,0 +1,55 @@
/**
* Created by tdzl2003 on 2/13/16.
*/
const fetch = require('isomorphic-fetch');
const host = process.env.PUSHY_REGISTRY || 'http://pushy.reactnative.cn';
const fs = require('fs-promise');
let session = undefined;
let fileSession = undefined;
exports.loadSession = async function() {
if (await fs.exists('.pushy')) {
try {
session = JSON.parse(await fs.readFile('.pushy', 'utf8'));
} catch (e) {
console.error('Failed to parse file `.pushy`. Try to remove it manually.');
throw e;
}
}
}
exports.getSession = function(){
return session;
}
exports.replaceSession = function(newSession) {
session = newSession;
}
exports.saveSession = async function(){
// Only save on change.
if (session != fileSession) {
const current = session;
const data = JSON.stringify(current, null, 4);
await fs.writeFile('.pushy', data, 'utf8');
fileSession = current;
}
}
function queryWithBody(method){
return async function(api, body) {
const resp = await fetch(host + api, {
method: 'post',
headers: {
'Content-Type': 'application/json',
'X-AccessToken': session ? session.token : '',
},
body: JSON.stringify(body),
});
}
}
exports.post = queryWithBody('POST');
exports.put = queryWithBody('PUT');

18
local-cli/cli.json Normal file
View File

@ -0,0 +1,18 @@
{
"useCommand": true,
"defaultCommand": "help",
"commands": {
"login":{
"options": {
"username": {
}
}
},
"help": {
}
},
"globalOptions":{
}
}

24
local-cli/index.js Normal file
View File

@ -0,0 +1,24 @@
/**
* Created by tdzl2003 on 2/13/16.
*/
const userCommands = require('./user').commands;
function printUsage({args}) {
// const commandName = args[0];
// TODO: print usage of commandName, or print global usage.
console.log('Usage is under development now.')
console.log('Visit `https://github.com/reactnativecn/react-native-pushy` for early document.');
process.exit(1);
}
const commands = {
...userCommands,
help: printUsage,
};
exports.run = function () {
const argv = require('cli-arguments').parse(require('./cli.json'));
commands[argv.command](argv).catch(err=>console.error(err.stack));
};

13
local-cli/user.js Normal file
View File

@ -0,0 +1,13 @@
/**
* Created by tdzl2003 on 2/13/16.
*/
const {question} = require('./utils');
exports.commands = {
login: async function ({args}){
const username = args[0] || await question('user:');
const password = args[1] || await question('password:', true);
}
}

13
local-cli/utils.js Normal file
View File

@ -0,0 +1,13 @@
/**
* Created by tdzl2003 on 2/13/16.
*/
var read = require('read');
exports.question = function(query, password) {
return new Promise((resolve, reject)=>read({
prompt: query,
silent: password,
replace: password ? '*' : undefined,
}, (err, result)=> err ? reject(err) : resolve(result)));
}

63
react-native-pushy-cli/cli.js vendored Executable file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env node
/**
* Created by tdzl2003 on 2/13/16.
*/
var path = require('path');
var fs = require('fs');
var CLI_MODULE_PATH = function() {
return path.resolve(
process.cwd(),
'node_modules',
'react-native-pushy',
'local-cli'
);
};
var PACKAGE_JSON_PATH = function() {
return path.resolve(
process.cwd(),
'node_modules',
'react-native-pushy',
'package.json'
);
};
checkForVersionCommand();
require('babel-register')({
'plugins': [
'transform-async-to-generator',
'transform-strict-mode',
'transform-object-rest-spread',
'transform-es2015-parameters',
'transform-es2015-destructuring',
],
});
var cli;
var cliPath = CLI_MODULE_PATH();
if (fs.existsSync(cliPath)) {
cli = require(cliPath);
}
if (cli) {
cli.run();
} else {
console.error('`pushy install` is under development, please run `npm install react-native-pushy` to install pushy manually.');
process.exit(1);
}
function checkForVersionCommand() {
if (process.argv.indexOf('-v') >= 0 || process.argv[2] === 'version') {
console.log('react-native-pushy-cli: ' + require('./package.json').version);
try {
console.log('react-native-pushy: ' + require(PACKAGE_JSON_PATH()).version);
} catch (e) {
console.log('react-native-pushy: n/a - not inside a React Native project directory')
}
process.exit();
}
}

View File

@ -0,0 +1,31 @@
{
"name": "react-native-pushy-cli",
"version": "0.1.0",
"description": "Command tools for javaScript updater with `pushy` service for react native apps.",
"main": "index.js",
"bin": {
"pushy": "cli.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/reactnativecn/react-native-pushy.git"
},
"keywords": [
"react-native",
"ios",
"android",
"update"
],
"author": "reactnativecn",
"license": "BSD-3-Clause",
"bugs": {
"url": "https://github.com/reactnativecn/react-native-pushy/issues"
},
"homepage": "https://github.com/reactnativecn/react-native-pushy/tree/master/react-native-pushy-cli",
"dependencies": {
"babel-register": "^6.5.2"
}
}