working
This commit is contained in:
commit
74396f8426
11
index.js
Normal file
11
index.js
Normal 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
8
lib/hooks.js
Normal 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
146
lib/resolveAssetSource.js
Normal 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
55
local-cli/api.js
Normal 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
18
local-cli/cli.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"useCommand": true,
|
||||||
|
"defaultCommand": "help",
|
||||||
|
"commands": {
|
||||||
|
"login":{
|
||||||
|
"options": {
|
||||||
|
"username": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"globalOptions":{
|
||||||
|
}
|
||||||
|
}
|
24
local-cli/index.js
Normal file
24
local-cli/index.js
Normal 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
13
local-cli/user.js
Normal 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
13
local-cli/utils.js
Normal 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
63
react-native-pushy-cli/cli.js
vendored
Executable 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();
|
||||||
|
}
|
||||||
|
}
|
31
react-native-pushy-cli/package.json
Normal file
31
react-native-pushy-cli/package.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user