v1
This commit is contained in:
parent
16ba9b5400
commit
cee4adf86d
42
Readme.md
Normal file
42
Readme.md
Normal file
@ -0,0 +1,42 @@
|
||||
# Magento Typescript client
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm i @plastichub/magento
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
|
||||
import { Magento } from '@plastichub/magento';
|
||||
|
||||
process.on('unhandledRejection', (reason: string) => {
|
||||
console.error('Unhandled rejection, reason: ', reason);
|
||||
});
|
||||
|
||||
// init with profile.json : {
|
||||
// "username":"admin",
|
||||
// "password":"password"
|
||||
//}
|
||||
|
||||
await Magento.initWithProfile('~/.magento.json', 'https://shop.plastic-hub.com/rest/all');
|
||||
|
||||
// await Magento.init('https://shop.plastic-hub.com/rest/all', 'admin', 'password');
|
||||
console.log('Magento API Config', Magento.apiConfig);
|
||||
const storeApi = new StoreStoreRepositoryV1Api(Magento.apiConfig);
|
||||
const stores = await storeApi.storeStoreRepositoryV1GetListGet({});
|
||||
console.log('stores', stores);
|
||||
|
||||
```
|
||||
|
||||
### Re-generate API via Swagger
|
||||
|
||||
1. Grab your swagger config from (make sure you are logged in) [https://shop.plastic-hub.com/swagger](https://shop.plastic-hub.com/swagger)
|
||||
2. Drop the content at [https://app.swaggerhub.com/](https://app.swaggerhub.com/)
|
||||
3. Export client -> typescrip-node-fetch-client
|
||||
4. Include the generated api.ts
|
||||
5. Drop the typescript compiler error output in a file, eg ```tsc -p . > shop_errors```
|
||||
6. Run [./tools/clean_magento](./tools/clean_magento) to fix the swagger-io bugs for unresolved types
|
||||
7. Done ;-)
|
||||
1
api.js.map
Normal file
1
api.js.map
Normal file
File diff suppressed because one or more lines are too long
14
config.json
14
config.json
@ -1,14 +0,0 @@
|
||||
{
|
||||
"products_path": "../../products/products",
|
||||
"fragments_path": "../../products/bazar/fragments",
|
||||
"vendor_name": "Plastic Hub",
|
||||
"vendor_website": "www.precious-plastic.org",
|
||||
"vendor_products_external": "https://github.com/plastic-hub/products/tree/master/products/",
|
||||
"vendor_instagram": "https://www.instagram.com/plastichubcat",
|
||||
"vendor_youtube": "https://www.youtube.com/channel/UCuWDxJtV2pf5BefHEy09Cew/featured?view_as=subscriber",
|
||||
"vendor_github": "https://github.com/plastic-hub",
|
||||
"vendor_contact_email": "mailto://cgoflyn@gmail.com",
|
||||
"vendor_whatsapp": "tel://0034666894789",
|
||||
"vendor_facebook" : "https://precious-plastic.org/library/machines/",
|
||||
"vendor_blog" : "https://precious-plastic.org/"
|
||||
}
|
||||
55
configuration.d.ts
vendored
Normal file
55
configuration.d.ts
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Magento Community
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* OpenAPI spec version: 2.4
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
export interface ConfigurationParameters {
|
||||
apiKey?: string | ((name: string) => string);
|
||||
username?: string;
|
||||
password?: string;
|
||||
accessToken?: string | ((name: string, scopes?: string[]) => string);
|
||||
basePath?: string;
|
||||
}
|
||||
export declare class Configuration {
|
||||
/**
|
||||
* parameter for apiKey security
|
||||
* @param name security name
|
||||
* @memberof Configuration
|
||||
*/
|
||||
apiKey?: string | ((name: string) => string);
|
||||
/**
|
||||
* parameter for basic security
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof Configuration
|
||||
*/
|
||||
username?: string;
|
||||
/**
|
||||
* parameter for basic security
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof Configuration
|
||||
*/
|
||||
password?: string;
|
||||
/**
|
||||
* parameter for oauth2 security
|
||||
* @param name security name
|
||||
* @param scopes oauth2 scope
|
||||
* @memberof Configuration
|
||||
*/
|
||||
accessToken?: string | ((name: string, scopes?: string[]) => string);
|
||||
/**
|
||||
* override base path
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof Configuration
|
||||
*/
|
||||
basePath?: string;
|
||||
constructor(param?: ConfigurationParameters);
|
||||
}
|
||||
26
configuration.js
Normal file
26
configuration.js
Normal file
@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
// tslint:disable
|
||||
/**
|
||||
* Magento Community
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* OpenAPI spec version: 2.4
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Configuration = void 0;
|
||||
class Configuration {
|
||||
constructor(param = {}) {
|
||||
this.apiKey = param.apiKey;
|
||||
this.username = param.username;
|
||||
this.password = param.password;
|
||||
this.accessToken = param.accessToken;
|
||||
this.basePath = param.basePath;
|
||||
}
|
||||
}
|
||||
exports.Configuration = Configuration;
|
||||
//# sourceMappingURL=configuration.js.map
|
||||
1
configuration.js.map
Normal file
1
configuration.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"configuration.js","sourceRoot":"","sources":["src/configuration.ts"],"names":[],"mappings":";AAAA,iBAAiB;AACjB;;;;;;;;;;GAUG;;;AAWH,MAAa,aAAa;IAoCtB,YAAY,QAAiC,EAAE;QAC3C,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IACnC,CAAC;CACJ;AA3CD,sCA2CC"}
|
||||
9
index.d.ts
vendored
Normal file
9
index.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
export declare const getToken: (url: any, user: any, password: any) => Promise<string>;
|
||||
export declare class Magento {
|
||||
static token: any;
|
||||
static apiConfig: any;
|
||||
static init: (baseUrl: string, username: string, password: string) => Promise<any>;
|
||||
static initWithProfile: (profilePath: string, baseUrl: any) => Promise<any>;
|
||||
}
|
||||
export declare const test: () => Promise<void>;
|
||||
export * as API from './api';
|
||||
75
index.js
Normal file
75
index.js
Normal file
@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
/*
|
||||
export * from './paths';
|
||||
export * from './format';
|
||||
export * from './log';
|
||||
export * from './types';
|
||||
export * from './formatter';
|
||||
export * from './main';
|
||||
export * from './test';
|
||||
*/
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.test = exports.Magento = exports.getToken = void 0;
|
||||
const configuration = require("./configuration");
|
||||
const os_1 = require("os");
|
||||
const read_1 = require("@plastichub/fs/read");
|
||||
const path = require("path");
|
||||
const api_1 = require("./api");
|
||||
exports.getToken = (url, user, password) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const api = new api_1.IntegrationAdminTokenServiceV1Api({
|
||||
basePath: url
|
||||
});
|
||||
return api.integrationAdminTokenServiceV1CreateAdminAccessTokenPost({
|
||||
username: user,
|
||||
password: password
|
||||
});
|
||||
});
|
||||
class Magento {
|
||||
}
|
||||
exports.Magento = Magento;
|
||||
Magento.token = null;
|
||||
Magento.apiConfig = null;
|
||||
Magento.init = (baseUrl, username, password) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const token = yield exports.getToken(baseUrl, username, password);
|
||||
api_1.setAuth({
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
Magento.token = token;
|
||||
Magento.apiConfig = new configuration.Configuration({
|
||||
basePath: baseUrl,
|
||||
accessToken: token
|
||||
});
|
||||
return Magento.token;
|
||||
});
|
||||
Magento.initWithProfile = (profilePath, baseUrl) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
if (profilePath[0] === '~') {
|
||||
profilePath = path.join(os_1.homedir(), profilePath.slice(1));
|
||||
}
|
||||
const profile = read_1.sync(path.resolve(profilePath), 'json') || {};
|
||||
return Magento.init(baseUrl || profile.baseUrl, profile.username, profile.password);
|
||||
});
|
||||
exports.test = () => __awaiter(void 0, void 0, void 0, function* () {
|
||||
process.on('unhandledRejection', (reason) => {
|
||||
console.error('Unhandled rejection, reason: ', reason);
|
||||
});
|
||||
yield Magento.initWithProfile('~/.magento.json', 'https://shop.plastic-hub.com/rest/all');
|
||||
// await Magento.init('https://shop.plastic-hub.com/rest/all', 'admin', '');
|
||||
console.log('Magento API Config', Magento.apiConfig);
|
||||
const storeApi = new api_1.StoreStoreRepositoryV1Api(Magento.apiConfig);
|
||||
const stores = yield storeApi.storeStoreRepositoryV1GetListGet({});
|
||||
console.log('stores', stores);
|
||||
});
|
||||
exports.API = require("./api");
|
||||
exports.test();
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
index.js.map
Normal file
1
index.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;EAQE;;;;;;;;;;;;AAEF,iDAAiD;AAEjD,2BAA6B;AAC7B,8CAAmD;AACnD,6BAA6B;AAE7B,+BAGc;AAGD,QAAA,QAAQ,GAAG,CAAO,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAmB,EAAE;IAEnE,MAAM,GAAG,GAAG,IAAI,uCAAiC,CAAC;QAC9C,QAAQ,EAAE,GAAG;KAChB,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,wDAAwD,CAAC;QAChE,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,QAAQ;KACrB,CAAC,CAAC;AACP,CAAC,CAAA,CAAA;AAED,MAAa,OAAO;;AAApB,0BAyBC;AAxBU,aAAK,GAAG,IAAI,CAAC;AACb,iBAAS,GAAG,IAAI,CAAC;AACjB,YAAI,GAAG,CAAO,OAAe,EAAE,QAAgB,EAAE,QAAgB,EAAE,EAAE;IACxE,MAAM,KAAK,GAAG,MAAM,gBAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1D,aAAO,CAAC;QACJ,OAAO,EAAE;YACL,eAAe,EAAE,UAAU,KAAK,EAAE;SACrC;KACJ,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;IACtB,OAAO,CAAC,SAAS,GAAG,IAAI,aAAa,CAAC,aAAa,CAAC;QAChD,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,KAAK;KACrB,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,KAAK,CAAC;AACzB,CAAC,CAAA,CAAA;AAEM,uBAAe,GAAG,CAAO,WAAmB,EAAE,OAAO,EAAE,EAAE;IAC5D,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;QACxB,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,YAAO,EAAE,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;KAC5D;IACD,MAAM,OAAO,GAAQ,WAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IACnE,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;AACxF,CAAC,CAAA,CAAA;AAEQ,QAAA,IAAI,GAAG,GAAS,EAAE;IAE3B,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAc,EAAE,EAAE;QAChD,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,MAAM,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,CAAC,eAAe,CAAC,iBAAiB,EAAE,uCAAuC,CAAC,CAAC;IAC1F,4EAA4E;IAC5E,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,+BAAyB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,gCAAgC,CAAC,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAClC,CAAC,CAAA,CAAA;AAED,+BAA6B;AAE7B,YAAI,EAAE,CAAC"}
|
||||
97
package.json
97
package.json
@ -1,112 +1,49 @@
|
||||
{
|
||||
"name": "@plastichub/cli",
|
||||
"version": "1.0.10",
|
||||
"name": "@plastichub/magento",
|
||||
"version": "1.0.13",
|
||||
"description": "",
|
||||
"main": "./build/main.js",
|
||||
"main": "./main.js",
|
||||
"types": "./index.d.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"help": "node build/main.js --help",
|
||||
"build": "tsc -p .",
|
||||
"typings": "tsc -p . --declaration",
|
||||
"dev": "tsc -w -p ."
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/plastic-hub/lang.git"
|
||||
"url": "git+https://git.osr-plastic.org/osr-plastic/magento-ts-client.git"
|
||||
},
|
||||
"author": "",
|
||||
"bin": {
|
||||
"ph-cli": "build/main.js"
|
||||
"magento-client": "build/main.js"
|
||||
},
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/plastic-hub/lang/issues"
|
||||
"url": "https://git.osr-plastic.org/osr-plastic/magento-ts-client/issues"
|
||||
},
|
||||
"homepage": "https://github.com/plastic-hub/lang#readme",
|
||||
"homepage": "https://git.osr-plastic.org/osr-plastic/magento-ts-client",
|
||||
"dependencies": {
|
||||
"@plastichub/fs": "^0.13.21",
|
||||
"@plastichub/osr-sync": "0.0.22",
|
||||
"@types/bluebird": "^3.5.29",
|
||||
"add": "^2.0.6",
|
||||
"apify": "^0.17.0",
|
||||
"axios": "^0.21.1",
|
||||
"bluebird": "^3.7.2",
|
||||
"@plastichub/core": "^0.1.4",
|
||||
"@plastichub/fs": "^0.13.25",
|
||||
"chalk": "^2.4.1",
|
||||
"cheerio": "^1.0.0-rc.3",
|
||||
"chokidar": "^3.3.1",
|
||||
"discourser": "^1.0.0",
|
||||
"download": "^8.0.0",
|
||||
"duration-timestamp": "^2.3.0",
|
||||
"errlop": "^2.1.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"cli-spinners": "^2.6.0",
|
||||
"defaults": "^1.0.3",
|
||||
"fast-glob": "^3.1.1",
|
||||
"filenamify": "^4.1.0",
|
||||
"googleapis": "^39.2.0",
|
||||
"inline-css": "^2.6.2",
|
||||
"isomorphic-unfetch": "^3.0.0",
|
||||
"js-beautify": "^1.11.0",
|
||||
"jsome": "^2.5.0",
|
||||
"json-to-pretty-yaml": "^1.2.2",
|
||||
"lodash": "^4.17.10",
|
||||
"markdown-table": "^2.0.0",
|
||||
"moment": "^2.26.0",
|
||||
"monocle-ts": "^1.2.0",
|
||||
"native-promise-pool": "^3.0.0",
|
||||
"ora": "^2.1.0",
|
||||
"partial.lenses": "^13.13.2",
|
||||
"pretty": "^2.0.0",
|
||||
"puppeteer": "^5.2.1",
|
||||
"ramda": "^0.25.0",
|
||||
"portable-fetch": "^3.0.0",
|
||||
"readline": "^1.3.0",
|
||||
"regexp.escape": "^1.1.0",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"showdown": "^1.9.1",
|
||||
"simple-git": "^2.6.0",
|
||||
"slash": "^3.0.0",
|
||||
"slugify": "^1.4.6",
|
||||
"source-map-support": "^0.5.16",
|
||||
"ts-node-dev": "^1.0.0-pre.44",
|
||||
"tslint": "^5.10.0",
|
||||
"turndown": "^7.0.0",
|
||||
"typescript": "^3.7.4",
|
||||
"which": "^2.0.2",
|
||||
"yargonaut": "^1.1.4",
|
||||
"yargs": "^15.0.2"
|
||||
"yargs": "^15.0.2",
|
||||
"yarn": "^1.22.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@bevry/links": "^1.1.1",
|
||||
"@bevry/update-contributors": "^1.0.1",
|
||||
"@types/node-fetch": "^2.5.7",
|
||||
"@typescript-eslint/eslint-plugin": "^2.30.0",
|
||||
"@typescript-eslint/parser": "^2.30.0",
|
||||
"@types/chalk": "^2.2.0",
|
||||
"@types/cheerio": "^0.22.15",
|
||||
"@types/chokidar": "^2.1.3",
|
||||
"@types/download": "^6.2.4",
|
||||
"@types/inline-css": "0.0.32",
|
||||
"@types/js-beautify": "^1.8.2",
|
||||
"@types/lodash": "^4.14.110",
|
||||
"@types/moment": "^2.13.0",
|
||||
"@types/node": "^13.1.1",
|
||||
"@types/ora": "^1.3.4",
|
||||
"@types/pretty": "^2.0.0",
|
||||
"@types/puppeteer": "^1.5.0",
|
||||
"@types/ramda": "^0.25.51",
|
||||
"@types/showdown": "^1.9.3",
|
||||
"@types/which": "^1.3.2",
|
||||
"@types/yargs": "^13.0.4",
|
||||
"@xblox/core": "^0.0.19",
|
||||
"assert-helpers": "^6.1.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-bevry": "^3.3.0",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-plugin-prettier": "^3.1.3",
|
||||
"jsdom": "^16.2.2",
|
||||
"kava": "^4.4.0",
|
||||
"prettier": "^2.0.5",
|
||||
"projectz": "^1.19.1",
|
||||
"surge": "^0.21.3",
|
||||
"typedoc": "^0.17.6",
|
||||
"valid-directory": "^1.6.0",
|
||||
"valid-module": "^1.0.0"
|
||||
"@types/yargs": "^13.0.4"
|
||||
}
|
||||
}
|
||||
|
||||
57618
src/api.ts
57618
src/api.ts
File diff suppressed because it is too large
Load Diff
66
src/configuration.ts
Normal file
66
src/configuration.ts
Normal file
@ -0,0 +1,66 @@
|
||||
// tslint:disable
|
||||
/**
|
||||
* Magento Community
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* OpenAPI spec version: 2.4
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
export interface ConfigurationParameters {
|
||||
apiKey?: string | ((name: string) => string);
|
||||
username?: string;
|
||||
password?: string;
|
||||
accessToken?: string | ((name: string, scopes?: string[]) => string);
|
||||
basePath?: string;
|
||||
}
|
||||
|
||||
export class Configuration {
|
||||
/**
|
||||
* parameter for apiKey security
|
||||
* @param name security name
|
||||
* @memberof Configuration
|
||||
*/
|
||||
apiKey?: string | ((name: string) => string);
|
||||
/**
|
||||
* parameter for basic security
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof Configuration
|
||||
*/
|
||||
username?: string;
|
||||
/**
|
||||
* parameter for basic security
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof Configuration
|
||||
*/
|
||||
password?: string;
|
||||
/**
|
||||
* parameter for oauth2 security
|
||||
* @param name security name
|
||||
* @param scopes oauth2 scope
|
||||
* @memberof Configuration
|
||||
*/
|
||||
accessToken?: string | ((name: string, scopes?: string[]) => string);
|
||||
/**
|
||||
* override base path
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof Configuration
|
||||
*/
|
||||
basePath?: string;
|
||||
|
||||
constructor(param: ConfigurationParameters = {}) {
|
||||
this.apiKey = param.apiKey;
|
||||
this.username = param.username;
|
||||
this.password = param.password;
|
||||
this.accessToken = param.accessToken;
|
||||
this.basePath = param.basePath;
|
||||
}
|
||||
}
|
||||
2
src/custom.d.ts
vendored
Normal file
2
src/custom.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare module 'portable-fetch';
|
||||
declare module 'url';
|
||||
@ -1,52 +0,0 @@
|
||||
#!/bin/sh
|
||||
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
|
||||
#
|
||||
# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update"
|
||||
|
||||
git_user_id=$1
|
||||
git_repo_id=$2
|
||||
release_note=$3
|
||||
|
||||
if [ "$git_user_id" = "" ]; then
|
||||
git_user_id=""
|
||||
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
||||
fi
|
||||
|
||||
if [ "$git_repo_id" = "" ]; then
|
||||
git_repo_id=""
|
||||
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
|
||||
fi
|
||||
|
||||
if [ "$release_note" = "" ]; then
|
||||
release_note=""
|
||||
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
|
||||
fi
|
||||
|
||||
# Initialize the local directory as a Git repository
|
||||
git init
|
||||
|
||||
# Adds the files in the local repository and stages them for commit.
|
||||
git add .
|
||||
|
||||
# Commits the tracked changes and prepares them to be pushed to a remote repository.
|
||||
git commit -m "$release_note"
|
||||
|
||||
# Sets the new remote
|
||||
git_remote=`git remote`
|
||||
if [ "$git_remote" = "" ]; then # git remote not defined
|
||||
|
||||
if [ "$GIT_TOKEN" = "" ]; then
|
||||
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
|
||||
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
|
||||
else
|
||||
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
git pull origin master
|
||||
|
||||
# Pushes (Forces) the changes in the local repository up to the remote repository
|
||||
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
|
||||
git push origin master 2>&1 | grep -v 'To https'
|
||||
|
||||
70
src/index.ts
70
src/index.ts
@ -1,6 +1,76 @@
|
||||
/*
|
||||
export * from './paths';
|
||||
export * from './format';
|
||||
export * from './log';
|
||||
export * from './types';
|
||||
export * from './formatter';
|
||||
export * from './main';
|
||||
export * from './test';
|
||||
*/
|
||||
|
||||
import * as configuration from './configuration';
|
||||
import * as debug from '@plastichub/core/debug';
|
||||
import { homedir } from 'os';
|
||||
import { sync as read } from '@plastichub/fs/read';
|
||||
import * as path from 'path';
|
||||
|
||||
import {
|
||||
setAuth, StoreStoreRepositoryV1Api,
|
||||
IntegrationAdminTokenServiceV1Api
|
||||
} from './api'
|
||||
|
||||
|
||||
export const getToken = async (url, user, password): Promise<string> => {
|
||||
|
||||
const api = new IntegrationAdminTokenServiceV1Api({
|
||||
basePath: url
|
||||
});
|
||||
return api.integrationAdminTokenServiceV1CreateAdminAccessTokenPost({
|
||||
username: user,
|
||||
password: password
|
||||
});
|
||||
}
|
||||
|
||||
export class Magento {
|
||||
static token = null;
|
||||
static apiConfig = null;
|
||||
static init = async (baseUrl: string, username: string, password: string) => {
|
||||
const token = await getToken(baseUrl, username, password);
|
||||
setAuth({
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
Magento.token = token;
|
||||
Magento.apiConfig = new configuration.Configuration({
|
||||
basePath: baseUrl,
|
||||
accessToken: token
|
||||
});
|
||||
return Magento.token;
|
||||
}
|
||||
|
||||
static initWithProfile = async (profilePath: string, baseUrl) => {
|
||||
if (profilePath[0] === '~') {
|
||||
profilePath = path.join(homedir(), profilePath.slice(1));
|
||||
}
|
||||
const profile: any = read(path.resolve(profilePath), 'json') || {};
|
||||
return Magento.init(baseUrl || profile.baseUrl, profile.username, profile.password);
|
||||
}
|
||||
}
|
||||
export const test = async () => {
|
||||
|
||||
process.on('unhandledRejection', (reason: string) => {
|
||||
console.error('Unhandled rejection, reason: ', reason);
|
||||
});
|
||||
|
||||
await Magento.initWithProfile('~/.magento.json', 'https://shop.plastic-hub.com/rest/all');
|
||||
// await Magento.init('https://shop.plastic-hub.com/rest/all', 'admin', '');
|
||||
console.log('Magento API Config', Magento.apiConfig);
|
||||
const storeApi = new StoreStoreRepositoryV1Api(Magento.apiConfig);
|
||||
const stores = await storeApi.storeStoreRepositoryV1GetListGet({});
|
||||
console.log('stores', stores);
|
||||
}
|
||||
|
||||
export * as API from './api';
|
||||
|
||||
test();
|
||||
@ -1,66 +1,5 @@
|
||||
import * as debug from '../..';
|
||||
import * as path from 'path';
|
||||
import { isArray, isString } from 'util';
|
||||
|
||||
import { files, read, csvToMarkdown, toHTML, md2html, exists } from '../../lib/';
|
||||
import { html_beautify } from 'js-beautify';
|
||||
import { sync as mkdir } from '@plastichub/fs/dir';
|
||||
import { substitute } from '../common/strings';
|
||||
|
||||
const md_tables = require('markdown-table');
|
||||
|
||||
export const parse_config = (config, root) => {
|
||||
if (Object.keys(config)) {
|
||||
for (const key in config) {
|
||||
let val = config[key];
|
||||
if (isArray(val)) {
|
||||
if (key !== 'authors') {
|
||||
config[key] = md2html(md_tables(val));
|
||||
}
|
||||
} else if (isString(val)) {
|
||||
if (val.endsWith('.csv')) {
|
||||
const parsed = path.parse(root);
|
||||
let csv = path.resolve(`${parsed.dir}/${parsed.base}/${val}`) as any;
|
||||
debug.info("Parsing CSV " + csv);
|
||||
if (exists(csv)) {
|
||||
csv = read(csv) || "";
|
||||
try {
|
||||
csv = md2html(csvToMarkdown(csv));
|
||||
config[key] = csv;
|
||||
} catch (e) {
|
||||
debug.error(`Error converting csv to md ${val}`);
|
||||
}
|
||||
} else {
|
||||
debug.error(`Can't find CSV file at ${csv}`, parsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const md_edit_wrap = (content, f, prefix = '', context = '') => {
|
||||
return html_beautify(`<div prefix="${prefix}" file="${path.parse(f).base}" context="${context}" class="fragment">${content}</div>`);
|
||||
}
|
||||
|
||||
export const read_fragments = (src, config, prefix = '', context = '') => {
|
||||
|
||||
if (!exists(src)) {
|
||||
debug.warn(`Create template folder ${src}`);
|
||||
mkdir(src);
|
||||
}
|
||||
let fragments = files(src, '*.html');
|
||||
fragments.map((f) => {
|
||||
config[path.parse(f).name] = md_edit_wrap(toHTML(f, true), f, prefix, context);
|
||||
});
|
||||
|
||||
fragments = files(src, '*.md');
|
||||
fragments.map((f) => {
|
||||
config[path.parse(f).name] = md_edit_wrap(toHTML(f, false), f, prefix, context);
|
||||
});
|
||||
return config;
|
||||
}
|
||||
|
||||
const _resolve = (config) => {
|
||||
for (const key in config) {
|
||||
if (config[key] && typeof config[key] == 'string') {
|
||||
|
||||
29
src/main.ts
29
src/main.ts
@ -1,31 +1,16 @@
|
||||
#!/usr/bin/env node
|
||||
import { defaults } from './_cli'; defaults();
|
||||
|
||||
import * as cli from 'yargs';
|
||||
import { register as registerMarkdown } from './commands/markdown'; registerMarkdown(cli);
|
||||
import { register as registerPDF2JPG } from './commands/pdf2jpg'; registerPDF2JPG(cli);
|
||||
import { register as registerSVG2JPG } from './commands/svg2jpg'; registerSVG2JPG(cli);
|
||||
import { register as registerWatch } from './commands/watch'; registerWatch(cli);
|
||||
import { register as registerAcademy } from './commands/academy'; registerAcademy(cli);
|
||||
import { register as registerOneArmy } from './commands/forumDownloader'; registerOneArmy(cli);
|
||||
import { register as registerTest } from './commands/tests'; registerTest(cli);
|
||||
import { register as registerV4Bom } from './commands/v4/bom'; registerV4Bom(cli);
|
||||
import { register as registerBazarProduct } from './commands/bazar/product'; registerBazarProduct(cli);
|
||||
import { register as registerBazarVendor } from './commands/bazar/vendor'; registerBazarVendor(cli);
|
||||
import { register as registerLibrary } from './commands/library'; registerLibrary(cli);
|
||||
import { register as registerSanitize } from './commands/common/sanitize-filename'; registerSanitize(cli);
|
||||
import { register as registerGHPIndex } from './commands/github/jekyll_machine'; registerGHPIndex(cli);
|
||||
import { register as registerGHProduct } from './commands/github/jekyll_product'; registerGHProduct(cli);
|
||||
import { register as registerProductDataSheet } from './commands/github/jekyll_product_datasheet'; registerProductDataSheet(cli);
|
||||
import { register as registerGHProjectIndex } from './commands/github/project_index'; registerGHProjectIndex(cli);
|
||||
import { register as registerMD_Thumbs } from './commands/github/md_thumbs'; registerMD_Thumbs(cli);
|
||||
import { register as registerMD_Page } from './commands/github/page'; registerMD_Page(cli);
|
||||
import { register as registerHowtoBackup } from './commands/howto'; registerHowtoBackup(cli);
|
||||
import { register as registerOADownload } from './commands/onearmy/download'; registerOADownload(cli);
|
||||
import { register as registerDiscourse } from './commands/forum/discourse'; registerDiscourse(cli);
|
||||
import * as cli from 'yargs';
|
||||
// import { register as registerMarkdown } from './commands/markdown'; registerMarkdown(cli);
|
||||
|
||||
const argv = cli.argv;
|
||||
|
||||
// import { test } from './test';
|
||||
// test();
|
||||
|
||||
|
||||
|
||||
if (argv.h || argv.help) {
|
||||
cli.showHelp();
|
||||
process.exit();
|
||||
|
||||
@ -1,106 +0,0 @@
|
||||
const Registry = require('rage-edit').Registry;
|
||||
|
||||
const SOFTWARE_CLASSES = 'HKCU\\Software\\Classes\\';
|
||||
|
||||
export const registerCommand = async options => {
|
||||
if (!options) throw new Error('options are empty');
|
||||
|
||||
const { name, icon, command, menu } = options;
|
||||
if (!name) throw new Error('name is not specified');
|
||||
if (!command) throw new Error('command is not specified');
|
||||
if (!menu) throw new Error('menuName is not specified');
|
||||
|
||||
try {
|
||||
await Registry.set(`${SOFTWARE_CLASSES}*\\shell\\${name}`);
|
||||
await Registry.set(`${SOFTWARE_CLASSES}*\\shell\\${name}`, '', menu);
|
||||
if (icon) await Registry.set(`${SOFTWARE_CLASSES}*\\shell\\${name}`, 'Icon', (icon.endsWith('.exe') ? `${icon},0` : icon));
|
||||
await Registry.set(`${SOFTWARE_CLASSES}*\\shell\\${name}\\command`, '', `"${command}" "%1"`);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const registerDirectoryCommand = async options => {
|
||||
if (!options) throw new Error('options are empty');
|
||||
|
||||
const { name, icon, command, menu } = options;
|
||||
if (!name) throw new Error('name is not specified');
|
||||
if (!command) throw new Error('command is not specified');
|
||||
if (!menu) throw new Error('menu is not specified');
|
||||
|
||||
try {
|
||||
await Registry.set(`${SOFTWARE_CLASSES}Directory\\shell\\${name}`);
|
||||
await Registry.set(`${SOFTWARE_CLASSES}Directory\\shell\\${name}`, '', menu);
|
||||
if (icon) await Registry.set(`${SOFTWARE_CLASSES}Directory\\shell\\${name}`, 'Icon', (icon.endsWith('.exe') ? `${icon},0` : icon));
|
||||
await Registry.set(`${SOFTWARE_CLASSES}Directory\\shell\\${name}\\command`, '', `"${command}" "%1"`);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const registerOpenWithCommand = async (extensions, options) => {
|
||||
if (!extensions || !extensions.length) throw new Error('extensions is not specified');
|
||||
if (!options) throw new Error('options are empty');
|
||||
|
||||
const { name, command } = options;
|
||||
if (!name) throw new Error('name is not specified');
|
||||
if (!command) throw new Error('command is not specified');
|
||||
|
||||
try {
|
||||
await Promise.all((await findExtensionNames(extensions)).map(async n => {
|
||||
await Registry.set(`${SOFTWARE_CLASSES}${n}`);
|
||||
await Registry.set(`${SOFTWARE_CLASSES}${n}\\shell\\${name}`);
|
||||
await Registry.set(`${SOFTWARE_CLASSES}${n}\\shell\\${name}\\command`, '', `"${command}" "%1"`);
|
||||
}));
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const removeCommand = async name => {
|
||||
if (!name) throw new Error('name is not specified');
|
||||
|
||||
try {
|
||||
await Registry.delete(`${SOFTWARE_CLASSES}*\\shell\\${name}`);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const removeDirectoryCommand = async name => {
|
||||
if (!name) throw new Error('name is not specified');
|
||||
|
||||
try {
|
||||
await Registry.delete(`${SOFTWARE_CLASSES}Directory\\shell\\${name}`);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const removeOpenWithCommand = async (extensions, name) => {
|
||||
if (!extensions) throw new Error('extensions is not specified');
|
||||
if (!name) throw new Error('name is not specified');
|
||||
|
||||
try {
|
||||
await Promise.all((await findExtensionNames(extensions)).map(async n => await Registry.delete(`${SOFTWARE_CLASSES}${n}\\shell\\${name}`)));
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
async function findExtensionNames (exts) {
|
||||
const { ses_root } = await Registry.get('HKCR');
|
||||
return Promise.all(Object.keys(ses_root).filter(e => exts.includes(e)).map(async k => (await Registry.get(`HKCR\\${k}`)).$values['']));
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
import { Browser, launch, Page, Response } from 'puppeteer';
|
||||
import { inspect, error, debug } from '../../log';
|
||||
import { capture_requests, capture_responses } from './network';
|
||||
let instance: Scope;
|
||||
import * as path from 'path';
|
||||
import { URL } from 'url';
|
||||
export const STATS_SUFFIX = '_stats.json';
|
||||
export const SESSION_EVENTS_SUFFIX = '_session.json';
|
||||
export const TRACE_SUFFIX = '_trace.json';
|
||||
const included_categories = ['devtools.timeline'];
|
||||
const _url_short = (url: string) =>
|
||||
new URL(url).hostname;
|
||||
|
||||
const _date_suffix = () =>
|
||||
new Date().toLocaleTimeString().replace(/:/g, '_');
|
||||
|
||||
const _random_suffix = () =>
|
||||
Math.random() * 100;
|
||||
|
||||
const _default_filename = (url: string) =>
|
||||
`${_url_short(url)}_${_random_suffix()}`;
|
||||
|
||||
export const default_path = (cwd: string, url: string) =>
|
||||
`${path.join(cwd, _default_filename(url))}${STATS_SUFFIX}`;
|
||||
|
||||
export const default_session_events_path = (cwd: string, url: string) =>
|
||||
`${path.join(cwd || process.cwd(), 'sessions', _default_filename(url))}${SESSION_EVENTS_SUFFIX}`;
|
||||
|
||||
export const default_trace_path = (cwd: string, url: string) =>
|
||||
`${path.join(cwd, _default_filename(url))}${TRACE_SUFFIX}`;
|
||||
|
||||
export class Scope {
|
||||
browser!: Browser;
|
||||
context!: any;
|
||||
page!: Page;
|
||||
args!: any;
|
||||
requests: any[] = [];
|
||||
responses: Response[] = [];
|
||||
eventBeacons: any[] = [];
|
||||
mutationBeacons: any[] = [];
|
||||
sessionSuffix: string = '';
|
||||
onResponse;
|
||||
onRequest;
|
||||
async init() {
|
||||
this.sessionSuffix = ' - ' + new Date().getTime();
|
||||
const args = [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-infobars',
|
||||
'--window-position=0,0',
|
||||
'--ignore-certifcate-errors',
|
||||
'--ignore-certifcate-errors-spki-list',
|
||||
'--user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3312.0 Safari/537.36"'
|
||||
];
|
||||
this.browser = await launch({ headless: this.args.headless === 'true', devtools: true,args:args});
|
||||
// const context = await this.browser.createIncognitoBrowserContext();
|
||||
this.page = await this.browser.newPage();
|
||||
// this.page = await context.newPage();
|
||||
|
||||
this.page.on('console', msg => {
|
||||
// error('Browser error:', msg);
|
||||
});
|
||||
this.page.on('error', msg => error('Browser Error:', msg));
|
||||
// this.page.on('pageerror', msg => error('Browser Page Error:', msg));
|
||||
// this.page.on('requestfailed', msg => error('Browser Page Request Error:', msg));
|
||||
|
||||
//capture_requests(this, this.page);
|
||||
//capture_responses(this, this.page);
|
||||
|
||||
// this.args.disableRequests !== 'true' && capture_requests(this, this.page);
|
||||
// this.args.disableResponses !== 'true' && capture_requests(this, this.page);
|
||||
// capture_responses(this, this.page);
|
||||
const page2 = this.page as any;
|
||||
//page2.setCacheEnabled(false);
|
||||
/*
|
||||
await page2._client.send('Security.setOverrideCertificateErrors', {
|
||||
override: true
|
||||
});
|
||||
*/
|
||||
await page2._client.on('Security.certificateError', (event: any) => {
|
||||
page2._client.send('Security.handleCertificateError', {
|
||||
eventId: event.eventId,
|
||||
action: 'continue' // ignore error and continue request
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const getScope = (cliArgs?: any) => {
|
||||
if (!instance) {
|
||||
instance = new Scope();
|
||||
instance.args = cliArgs;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
import { NavigationOptions } from 'puppeteer';
|
||||
export const defaultTenant = 1;
|
||||
export const userSessionsTab = (base: string) => `${base}/e/${defaultTenant}/#usersearchoverview;gtf=l_2_HOURS`;
|
||||
export const loginUrl = (base: string) => `${base}/login`;
|
||||
export const loginUrlDemoDev = () => `https://proxy-dev.dynatracelabs.com/sso/ProxyLocator.jsp`;
|
||||
export const defaultPageOptions = (): NavigationOptions => {
|
||||
return {
|
||||
timeout: 5000,
|
||||
waitUntil: 'networkidle2'
|
||||
}
|
||||
}
|
||||
|
||||
export const replay_api_overview = 'uemshareddetails/rumoverviewdata/usersearchoverview';
|
||||
const ts = () => {
|
||||
const d = new Date();
|
||||
return d.getHours() + '_' + d.getMinutes() + '_' + d.getSeconds();
|
||||
}
|
||||
export const sessionName = (url?: string) => `Pupeteer :${ts()}`;
|
||||
|
||||
export const maxSessionWaitingTime = 1000 * 60 * 3;
|
||||
export const responseRetryTime = 1000 * 8;
|
||||
export const defaultMutationRoot = '#mutationsRoot';
|
||||
export const defaultMutationTag = 'div';
|
||||
export const defaultHeavyMutations = 2000;
|
||||
export const defaultMediumMutations = 500;
|
||||
@ -1,186 +0,0 @@
|
||||
import { launch, Page } from 'puppeteer'
|
||||
import { readFileSync } from 'fs';
|
||||
import * as moment from 'moment';
|
||||
import { sync as unlink } from '@plastichub/fs/remove';
|
||||
import { async as iterator } from '@plastichub/fs/iterator';
|
||||
import {
|
||||
debug, inspect,
|
||||
Options, TraceEntry, TraceTiming,
|
||||
default_trace_path,
|
||||
ReportEntry,
|
||||
NetworkReportEntry,
|
||||
sizeToString,
|
||||
log,
|
||||
spinner,
|
||||
STATS_SUFFIX,
|
||||
TRACE_SUFFIX
|
||||
} from '../../';
|
||||
import { end_time } from './times';
|
||||
import { find_time } from './trace';
|
||||
import { rl } from './stdin';
|
||||
import { report, find_report, get_report } from './report';
|
||||
import { IProcessingNode } from '@plastichub/fs/interfaces';
|
||||
|
||||
const included_categories = ['devtools.timeline'];
|
||||
|
||||
export class Puppeteer {
|
||||
|
||||
static clean(url: string, options: Options) {
|
||||
iterator(options.cwd, {
|
||||
matching: [`*${STATS_SUFFIX}`, `*${TRACE_SUFFIX}`]
|
||||
}).then((it) => {
|
||||
let node: IProcessingNode = null;
|
||||
while (node = it.next()) {
|
||||
unlink(node.path);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static async begin(url: string, options: Options) {
|
||||
|
||||
const browser = await launch({
|
||||
headless: options.headless,
|
||||
devtools: false
|
||||
});
|
||||
return await browser.newPage();
|
||||
}
|
||||
static async crawler(url: string, options?: Options) {
|
||||
|
||||
const page = await this.begin(url, options);
|
||||
|
||||
}
|
||||
static async repl(url: string, options?: Options) {
|
||||
|
||||
const page = await this.begin(url, options);
|
||||
page.on('console', msg => inspect('Console Message:', msg.text()));
|
||||
|
||||
await page.goto(url, {
|
||||
timeout: 600000,
|
||||
waitUntil: 'networkidle0'
|
||||
});
|
||||
|
||||
const readline = rl(`${url}#`, (line: string) => {
|
||||
page.evaluate(line).then((results) => {
|
||||
inspect(`Did evaluate ${line} to `, results);
|
||||
})
|
||||
}, () => this.end(page));
|
||||
}
|
||||
|
||||
|
||||
static async end(page: Page) {
|
||||
|
||||
const browser = await page.browser();
|
||||
await page.close();
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
static async summary(url: string, options?: Options) {
|
||||
|
||||
const browser = await launch({
|
||||
headless: options.headless,
|
||||
devtools: true
|
||||
});
|
||||
const page = await browser.newPage();
|
||||
await page.goto(url, {
|
||||
timeout: 600000,
|
||||
waitUntil: 'networkidle0'
|
||||
});
|
||||
const metrics = await page.metrics();
|
||||
await this.end(page);
|
||||
return metrics;
|
||||
}
|
||||
|
||||
static async detail(url: string, options?: Options) {
|
||||
|
||||
const network_stats = report();
|
||||
const ReceivedTotal = get_report(network_stats, 'Received Total');
|
||||
const ReceivedStyleSheets = get_report(network_stats, 'Received Stylesheets');
|
||||
const ReceivedScripts = get_report(network_stats, 'Received Scripts');
|
||||
const ReceivedHTML = get_report(network_stats, 'Received HTML');
|
||||
const ReceivedImages = get_report(network_stats, 'Received Images');
|
||||
const ReceivedJSON = get_report(network_stats, 'Received JSON');
|
||||
const ReceivedFonts = get_report(network_stats, 'Received Fonts');
|
||||
const ReceivedBinary = get_report(network_stats, 'Received Binary');
|
||||
const MimeMap = {
|
||||
'application/javascript': ReceivedScripts,
|
||||
'text/javascript': ReceivedScripts,
|
||||
'text/css': ReceivedStyleSheets,
|
||||
'text/html': ReceivedHTML,
|
||||
'image/png': ReceivedImages,
|
||||
'image/gif': ReceivedImages,
|
||||
'image/svg+xml': ReceivedImages,
|
||||
'application/json': ReceivedJSON,
|
||||
'application/octet-stream': ReceivedBinary,
|
||||
'font/woff2': ReceivedFonts,
|
||||
'application/font-woff2': ReceivedFonts
|
||||
}
|
||||
|
||||
const traceFile = default_trace_path(options.cwd, url);
|
||||
|
||||
const page = await this.begin(url, options);
|
||||
await page.tracing.start({
|
||||
path: traceFile,
|
||||
categories: included_categories
|
||||
});
|
||||
await page.goto(url, {
|
||||
timeout: 600000,
|
||||
waitUntil: 'networkidle0'
|
||||
});
|
||||
const metrics = await (page as any)._client.send('Performance.getMetrics');
|
||||
const nowTs = new Date().getTime();
|
||||
// const navigationStart = getTimeFromMetrics(metrics, 'NavigationStart');
|
||||
const navigationStart = find_time(metrics, 'Timestamp') + nowTs;
|
||||
await page.tracing.stop();
|
||||
|
||||
// --- extracting data from trace.json ---
|
||||
const tracing = JSON.parse(readFileSync(traceFile, 'utf8'));
|
||||
|
||||
const dataReceivedEvents = tracing.traceEvents.filter(x => x.name === 'ResourceReceivedData');
|
||||
const dataResponseEvents = tracing.traceEvents.filter(x => x.name === 'ResourceReceiveResponse');
|
||||
|
||||
// find resource in responses or return default empty
|
||||
const content_response = (requestId: string): TraceEntry => dataResponseEvents.find((x) =>
|
||||
x.args.data.requestId === requestId)
|
||||
|| { args: { data: { encodedDataLength: 0 } } };
|
||||
|
||||
const report_per_mime = (mime: string): NetworkReportEntry => MimeMap[mime] || get_report(network_stats, mime);
|
||||
|
||||
// our iteration over the trace
|
||||
// @TODO: convert to a better tree structure to avoid O(n) lookups
|
||||
// @TODO: emit to extensions: events & aspects
|
||||
// @TODO: calculate times
|
||||
// @TODO: filter
|
||||
// @TODO: options.mask
|
||||
// @TODO: this iterator might get async
|
||||
ReceivedTotal.value = dataReceivedEvents.reduce((first, x) => {
|
||||
const content = content_response(x.args.data.requestId);
|
||||
const data = content.args.data;
|
||||
const report = report_per_mime(data.mimeType);
|
||||
if (data.fromCache === false) {
|
||||
report.value += x.args.data.encodedDataLength
|
||||
report.count++;
|
||||
} else {
|
||||
report.cached_count++;
|
||||
}
|
||||
ReceivedTotal.count++;
|
||||
return first + x.args.data.encodedDataLength;
|
||||
}, ReceivedTotal.value);
|
||||
|
||||
// calulate finals
|
||||
[ReceivedTotal, ReceivedHTML, ReceivedImages, ReceivedJSON,
|
||||
ReceivedScripts, ReceivedFonts, ReceivedBinary
|
||||
].forEach((r) => r.formatted = sizeToString(r.value))
|
||||
|
||||
// --- end extracting data from trace.json ---
|
||||
|
||||
let results = [];
|
||||
|
||||
// lights off
|
||||
await this.end(page);
|
||||
|
||||
return {
|
||||
times: [],
|
||||
network: network_stats
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,176 +0,0 @@
|
||||
import { Page, Request, Response } from 'puppeteer';
|
||||
import { sessionName, maxSessionWaitingTime, defaultPageOptions, userSessionsTab } from './constants';
|
||||
import * as debug from '../../log';
|
||||
import { Scope } from './Scope';
|
||||
import { parse } from 'url';
|
||||
import { navigateToUserSessions } from './processes';
|
||||
|
||||
const debugRequests = true;
|
||||
const debugResponses = false;
|
||||
export const default_postdata = (request: Request): any => request.postData && request.postData() || {};
|
||||
export type ResponseMatch = (request: any) => boolean;
|
||||
export const HasUserSessions = (request: Request) => (default_postdata(request).users)
|
||||
export const MyUserSessions = (url: string, request: Request) => SessionWithName(request, sessionName(url));
|
||||
export const SessionWithName = (request: Request, name: string) => {
|
||||
const data = default_postdata(request).users || [];
|
||||
return data.find((user: any) => user.id === name)
|
||||
}
|
||||
export type ResponseResolve = Response & {
|
||||
data: any;
|
||||
}
|
||||
const default_prepare = (requests: Request[]): Request[] => {
|
||||
return requests;
|
||||
};
|
||||
|
||||
const default_filter_json = (r: Request) => ((r.headers()['content-type'] || '').startsWith('application/json;')) === true;
|
||||
const responses = async function (requests: Request[]) { return Promise.all(requests.map(r => r.response()!.json())) };
|
||||
|
||||
export const findRequest = (url: string, requests: Request[], match?: ResponseMatch): Request[] => {
|
||||
url = decodeURIComponent(url);
|
||||
if (!match) {
|
||||
return requests.filter((request) => request.url().indexOf(url) !== -1);
|
||||
} else {
|
||||
const results = requests.filter((request) => request.url().indexOf(url) !== -1);
|
||||
return results.filter((r) => match!(r));
|
||||
}
|
||||
}
|
||||
|
||||
export function waitForResponse(url: string, scope: Scope, match: ResponseMatch, timeout: number = 5000): Promise<any[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
|
||||
let requests = default_prepare(scope.requests).filter(default_filter_json).filter(r => r.response() != null);
|
||||
requests = requests.filter((request) => request.url().indexOf(url) !== -1);
|
||||
responses(requests).then((responses) => {
|
||||
const ret = responses.filter(match);
|
||||
if (ret.length) {
|
||||
resolve(ret);
|
||||
} else {
|
||||
reject('cant find anything yet');
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
debug.error('waitForResponse Error ', error);
|
||||
}
|
||||
}, timeout);
|
||||
})
|
||||
}
|
||||
export function waitForResponseNTimes(url: string, scope: Scope, match: ResponseMatch, timeout: number = 5000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const maxTime = maxSessionWaitingTime;
|
||||
const retryTime = 8000;
|
||||
let reachedTimeOut = false;
|
||||
let interval: any = null;
|
||||
interval = setInterval(() => {
|
||||
if (reachedTimeOut) {
|
||||
clearInterval(interval);
|
||||
debug.error('reached max');
|
||||
reject('reached maximum timeout');
|
||||
return;
|
||||
}
|
||||
onReload(scope).then(() => {
|
||||
scope.page.reload().then(() => {
|
||||
debug.info('retry ');
|
||||
waitForResponse(url, scope, match, retryTime).then((session) => {
|
||||
debug.inspect('got my session', session);
|
||||
clearInterval(interval);
|
||||
resolve(session);
|
||||
}).catch((e) => {
|
||||
debug.error('found nothing');
|
||||
})
|
||||
}).catch((e) => {
|
||||
console.error('error loading page : ', e);
|
||||
});
|
||||
});
|
||||
}, retryTime);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
reachedTimeOut = true;
|
||||
clearInterval(interval);
|
||||
reject('max timeout reached');
|
||||
}, maxTime);
|
||||
});
|
||||
};
|
||||
|
||||
export async function capture_request(where: any[], request: Request) {
|
||||
debugRequests && debug.inspect('Request', { url: request.url(), data: request.postData() });
|
||||
where.push({ url: request.url(), data: await request.postData(), request: request });
|
||||
debugRequests && debug.inspect('requests', where.map(r => r.url));
|
||||
}
|
||||
|
||||
export async function capture_response(where: any[], response: Response) {
|
||||
debugResponses && debug.inspect('Response', { url: response.url(), data: await response.json() });
|
||||
where.push(response);
|
||||
}
|
||||
|
||||
export async function capture_requests(scope: Scope, page: Page) {
|
||||
|
||||
await page.setRequestInterception(true);
|
||||
|
||||
scope.requests = [];
|
||||
page.on('request', (interceptedRequest: Request) => {
|
||||
|
||||
if(scope.onRequest){
|
||||
scope.onRequest(interceptedRequest, scope);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const url = decodeURIComponent(interceptedRequest.url());
|
||||
const parsed = parse(url, true);
|
||||
if (url.includes('.css') || url.includes('.svg')) {
|
||||
interceptedRequest.abort();
|
||||
return;
|
||||
|
||||
}
|
||||
const query = parsed.query;
|
||||
const isJson = (interceptedRequest.headers()['content-type'] || '').startsWith('application/json') === true;
|
||||
if (isJson) {
|
||||
// capture_request(scope.requests, interceptedRequest);
|
||||
//debugRequests && debug.inspect('q ' + query['contentType'] + ' ' + url);
|
||||
}
|
||||
interceptedRequest.continue();
|
||||
} catch (e) {
|
||||
debug.error('error parsing request ', e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function capture_responses(scope: Scope, page: Page) {
|
||||
try {
|
||||
// await page.setRequestInterception(true);
|
||||
} catch (e) {
|
||||
debug.error('error intercepting responses', e);
|
||||
}
|
||||
scope.responses = [];
|
||||
page.on('response', response => {
|
||||
try {
|
||||
const isJson = (response.headers()['content-type'] || '').startsWith('application/json;') === true;
|
||||
const url = response.url();
|
||||
|
||||
if (response.status() === 200) {
|
||||
if (isJson) {
|
||||
capture_response(scope.responses, response);
|
||||
}
|
||||
if (scope.onResponse) {
|
||||
scope.onResponse(response, scope);
|
||||
}
|
||||
} else {
|
||||
debugResponses && debug.error(`Error loading ${url} : ${response.status()}`);
|
||||
}
|
||||
} catch (e) {
|
||||
debugResponses && debug.error('Error parsing response');
|
||||
}
|
||||
});
|
||||
}
|
||||
export async function onReload(scope: Scope) {
|
||||
scope.requests = [];
|
||||
try {
|
||||
await scope.page.setRequestInterception(false);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
await scope.page.setRequestInterception(true);
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
import { Page, Request } from 'puppeteer';
|
||||
import { Options } from './types';
|
||||
import { loginUrl, defaultPageOptions, userSessionsTab, loginUrlDemoDev } from './constants';
|
||||
|
||||
export async function loginFrontEnd(page: Page, options: Options) {
|
||||
// await page.goto(loginUrl(options.dynatraceUrl), defaultPageOptions());
|
||||
await page.type('#user', 'admin');
|
||||
await page.type('#password', 'admin');
|
||||
await page.click('#login-form > .maindiv > .logindiv > .submitdiv > .button');
|
||||
await page.waitForSelector('.tenant-selector');
|
||||
await page.click('.textboxdiv > .tenant-selector:nth-child(2)');
|
||||
}
|
||||
|
||||
export async function loginDemoDev(page: Page, options: Options) {
|
||||
await page.goto(loginUrlDemoDev(), defaultPageOptions());
|
||||
await page.type('#IDToken1', 'guenter.baumgart@ruxit.com');
|
||||
await page.click('.maindiv > .logindiv > form > div > #formsubmit');
|
||||
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(1);
|
||||
console.log('time out');
|
||||
}, 20 * 1000)
|
||||
});
|
||||
|
||||
console.log('logged in 1/2!');
|
||||
|
||||
|
||||
/*
|
||||
const puppeteer = require('puppeteer');
|
||||
|
||||
(async () => {
|
||||
const browser = await puppeteer.launch()
|
||||
const page = await browser.newPage()
|
||||
|
||||
await page.waitForSelector('.logindiv > form > .textboxdiv > .emailLoginIcon > #IDToken1')
|
||||
await page.click('.logindiv > form > .textboxdiv > .emailLoginIcon > #IDToken1')
|
||||
|
||||
await page.waitForSelector('.maindiv > .logindiv > form > div > #formsubmit')
|
||||
await page.click('.maindiv > .logindiv > form > div > #formsubmit')
|
||||
|
||||
const navigationPromise = page.waitForNavigation()
|
||||
await navigationPromise
|
||||
|
||||
await page.waitForSelector('.logindiv > form > .margin-bottom\3A > .passwordIcon > #IDToken2')
|
||||
await page.click('.logindiv > form > .margin-bottom\3A > .passwordIcon > #IDToken2')
|
||||
|
||||
await page.waitForSelector('.logindiv > form > fieldset > div > #IDToken3')
|
||||
await page.click('.logindiv > form > fieldset > div > #IDToken3')
|
||||
|
||||
await page.waitForSelector('form > fieldset > #button-base > div > #loginButton_0')
|
||||
await page.click('form > fieldset > #button-base > div > #loginButton_0')
|
||||
|
||||
await navigationPromise
|
||||
|
||||
await navigationPromise
|
||||
|
||||
await navigationPromise
|
||||
|
||||
await browser.close()
|
||||
})()
|
||||
*/
|
||||
|
||||
//await page.type('#password', 'admin');
|
||||
//await page.click('#login-form > .maindiv > .logindiv > .submitdiv > .button');
|
||||
//await page.waitForSelector('.tenant-selector');
|
||||
//await page.click('.textboxdiv > .tenant-selector:nth-child(2)');
|
||||
}
|
||||
|
||||
export async function navigateToUserSessions(page: Page, options: Options) {
|
||||
// await page.goto(userSessionsTab(options.dynatraceUrl), defaultPageOptions());
|
||||
}
|
||||
|
||||
|
||||
export async function navigateToUserLocalhost(page: Page, options?: Options) {
|
||||
// await page.goto('http://localhost/', defaultPageOptions());
|
||||
}
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
import { NetworkReportEntry } from './types';
|
||||
const report_item = (name: string): NetworkReportEntry => {
|
||||
return {
|
||||
name: name,
|
||||
value: 0,
|
||||
formatted: '',
|
||||
count: 0,
|
||||
cached_count: 0,
|
||||
external_count: 0,
|
||||
local_count: 0,
|
||||
times: {
|
||||
end: 0,
|
||||
formatted: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const report = () => {
|
||||
return [
|
||||
report_item('Received Total'),
|
||||
report_item('Received Stylesheets'),
|
||||
report_item('Received Scripts'),
|
||||
report_item('Received HTML'),
|
||||
report_item('Received JSON'),
|
||||
report_item('Received Images'),
|
||||
report_item('Received Fonts'),
|
||||
report_item('Received Binary')
|
||||
]
|
||||
}
|
||||
|
||||
export const find_report = (where: any[], name: string) => where.find((media) => media.name === name);
|
||||
|
||||
export const get_report = (where: any[], type: string) => {
|
||||
let record = find_report(where, type);
|
||||
if (!record) {
|
||||
record = report_item(type);
|
||||
where.push(record);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
import { createInterface, ReadLine } from 'readline';
|
||||
import { Page } from 'puppeteer';
|
||||
import chalk from 'chalk';
|
||||
|
||||
|
||||
|
||||
export const rl = (prompt: string, onLine?: (line: string) => void, onClose?: () => {}) => {
|
||||
const rl = createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
prompt: chalk.green(prompt)
|
||||
})
|
||||
console.log('start stdin: ' + prompt);
|
||||
rl.prompt()
|
||||
rl.on('line', (line) => {
|
||||
if(!line){
|
||||
return;
|
||||
}
|
||||
try {
|
||||
onLine(line);
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
rl.prompt()
|
||||
}
|
||||
})
|
||||
rl.on('close', () => {
|
||||
rl.close()
|
||||
onClose();
|
||||
});
|
||||
return rl;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import { TraceEntry } from './types'
|
||||
export const end_time = (entry: TraceEntry): number => {
|
||||
const timing = entry.args.data.timing;
|
||||
const start = timing.requestTime;
|
||||
const received = entry.ts;
|
||||
//it might be more accurate to calc this with the header times
|
||||
const headersReceived = start + timing.receiveHeadersEnd / 1000;
|
||||
let responseReceived = headersReceived;
|
||||
responseReceived = Math.min(responseReceived, headersReceived);
|
||||
responseReceived = Math.max(responseReceived, start);
|
||||
return Math.max(-1, responseReceived);
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
import { NetworkReportEntry, TraceEntry } from "./types";
|
||||
|
||||
export const find_time = (metrics, name) =>
|
||||
metrics.metrics.find(x => x.name === name).value;
|
||||
|
||||
export const all_with_name = (where: NetworkReportEntry[], name: string) =>
|
||||
where.filter((entry) => entry.name === name);
|
||||
|
||||
/*
|
||||
export const tree = (entries: TraceEntry[]) => {
|
||||
const tasks = [];
|
||||
let currentTask;
|
||||
|
||||
for (const event of entries) {
|
||||
// Only look at X (Complete), B (Begin), and E (End) events as they have most data
|
||||
if (event.ph !== 'X' && event.ph !== 'B' && event.ph !== 'E') continue;
|
||||
|
||||
// Update currentTask based on the elapsed time.
|
||||
// The next event may be after currentTask has ended.
|
||||
while (
|
||||
currentTask &&
|
||||
Number.isFinite(currentTask.endTime) &&
|
||||
currentTask.endTime <= event.ts
|
||||
) {
|
||||
currentTask = currentTask.parent;
|
||||
}
|
||||
|
||||
if (!currentTask) {
|
||||
// We can't start a task with an end event
|
||||
if (event.ph === 'E') {
|
||||
throw new Error('Fatal trace logic error');
|
||||
}
|
||||
|
||||
currentTask = entries._createNewTaskNode(event);
|
||||
tasks.push(currentTask);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (event.ph === 'X' || event.ph === 'B') {
|
||||
// We're starting a nested event, create it as a child and make it the currentTask
|
||||
const newTask = entries._createNewTaskNode(event, currentTask);
|
||||
tasks.push(newTask);
|
||||
currentTask = newTask;
|
||||
} else {
|
||||
if (currentTask.event.ph !== 'B') {
|
||||
throw new Error('Fatal trace logic error');
|
||||
}
|
||||
|
||||
// We're ending an event, update the end time and the currentTask to its parent
|
||||
currentTask.endTime = event.ts;
|
||||
currentTask = currentTask.parent;
|
||||
}
|
||||
}
|
||||
return tasks;
|
||||
}
|
||||
*/
|
||||
@ -1,124 +0,0 @@
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// Application types
|
||||
//
|
||||
export enum OutputTarget {
|
||||
STDOUT = 'console',
|
||||
FILE = 'file'
|
||||
}
|
||||
|
||||
export enum OutputFormat {
|
||||
text = 'text',
|
||||
json = 'json'
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
// @TODO: support many
|
||||
url?: string;
|
||||
format?: OutputFormat;
|
||||
// @TODO: support many
|
||||
target?: OutputTarget;
|
||||
headless?: boolean;
|
||||
// output path
|
||||
path?: string;
|
||||
// @TODO: required to pick profile/config files
|
||||
cwd?: string;
|
||||
// @TODO: time of sesssion, mapped to Puppeteer waitUntil, if it's a number, the session will be opened for that
|
||||
// time window, time=-1 means infinity, useful for repl. sessions
|
||||
time?: number;
|
||||
// @TODO: reload interval
|
||||
reload?: number;
|
||||
// @TODO: repl. --repl=true=interactive or repl=path to specify script
|
||||
repl?: string | boolean;
|
||||
// TODO: colored ouput
|
||||
colors?: boolean;
|
||||
}
|
||||
|
||||
// options for certain categories as network, rendering,...
|
||||
export interface OptionEx {
|
||||
include?: string | string[];
|
||||
exclude?: string | string[];
|
||||
query?: string | string[];
|
||||
}
|
||||
|
||||
export type OptionsEx = Options & {
|
||||
launchOptions?: {
|
||||
// puppeteer launch options
|
||||
}
|
||||
waitOptions?: {
|
||||
// puppeteer wait options: wait for selector,...
|
||||
}
|
||||
replOptions?: {
|
||||
script?: string;
|
||||
}
|
||||
}
|
||||
|
||||
export type OutputResult = boolean;
|
||||
|
||||
export interface ReportEntry {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export type NetworkReportEntry = ReportEntry & {
|
||||
value: number;
|
||||
formatted: string;
|
||||
count: number;
|
||||
cached_count: number;
|
||||
external_count: number;
|
||||
local_count: number;
|
||||
times?: {
|
||||
end: number,
|
||||
formatted: string;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//
|
||||
// Foreign data types (trace data)
|
||||
//
|
||||
|
||||
// type for a network resource's timing
|
||||
export interface TraceTiming {
|
||||
requestTime: number;
|
||||
proxyStart: number;
|
||||
proxyEnd: number;
|
||||
dnsStart: number;
|
||||
dnsEnd: number;
|
||||
connectStart: number;
|
||||
connectEnd: number;
|
||||
sslStart: number;
|
||||
sslEnd: number;
|
||||
workerStart: number;
|
||||
workerReady: number;
|
||||
sendStart: number;
|
||||
sendEnd: number;
|
||||
receiveHeadersEnd: number;
|
||||
pushStart: number;
|
||||
pushEnd: number;
|
||||
}
|
||||
|
||||
export interface TraceData {
|
||||
requestId: string;
|
||||
frame: string;
|
||||
statusCode: number;
|
||||
mimeType: string;
|
||||
encodedDataLength: number;
|
||||
fromCache: boolean;
|
||||
fromServiceWorker: boolean;
|
||||
timing: TraceTiming;
|
||||
}
|
||||
export interface TraceArgs {
|
||||
data: TraceData;
|
||||
}
|
||||
|
||||
export interface TraceEntry {
|
||||
pid: number;
|
||||
tid: number;
|
||||
ts: number;
|
||||
ph: string; // B: begin, | E: end; For async events: S: start, F: finish
|
||||
cat: string;
|
||||
name: string;
|
||||
args: TraceArgs;
|
||||
tts: number;
|
||||
s: string;
|
||||
}
|
||||
13
src/test.ts
Normal file
13
src/test.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import * as debug from '@plastichub/core/debug';
|
||||
import { sync as read } from '@plastichub/fs/read';
|
||||
|
||||
import { homedir } from 'os';
|
||||
import * as path from 'path';
|
||||
|
||||
|
||||
export const test = () => {
|
||||
debug.error('home dir ' + homedir());
|
||||
|
||||
}
|
||||
|
||||
test();
|
||||
42
tools/clean_magento.js
Normal file
42
tools/clean_magento.js
Normal file
@ -0,0 +1,42 @@
|
||||
const read = require('@plastichub/fs/read').sync;
|
||||
const path = require('path');
|
||||
const write = require('@plastichub/fs/write').sync;
|
||||
|
||||
|
||||
const content = read('./shop_errors.txt').split('\n');
|
||||
|
||||
let api = read('./src/shop/api.ts');
|
||||
|
||||
var lineReader = require('readline').createInterface({
|
||||
input: require('fs').createReadStream('shop_errors.txt')
|
||||
});
|
||||
|
||||
var types = {};
|
||||
|
||||
lineReader.on('line', function (line) {
|
||||
// create a map of the unresolved types
|
||||
if (line.indexOf('src/shop/api.ts')) {
|
||||
const type = line.split("'")[1];
|
||||
if (type) {
|
||||
if (!types[type]) {
|
||||
types[type] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
String.prototype.replaceAll = function (search, replacement) {
|
||||
var target = this;
|
||||
return target.split(search).join(replacement);
|
||||
};
|
||||
|
||||
|
||||
lineReader.on('close', function (e) {
|
||||
for (var t in types) {
|
||||
t = t.replace(/[^\x00-\x7F]/g, ""); // non ascii
|
||||
t = t.replace(/[\u0000-\u001F\u007F-\u009F]/g, "");//typescript term characters
|
||||
t = t.replace(/[\u{0080}-\u{FFFF}]/gu,"");//terminal plugin special characters
|
||||
api = api.replaceAll(t, 'any');
|
||||
}
|
||||
write('./src/shop/api.ts', api);
|
||||
});
|
||||
@ -7,7 +7,7 @@
|
||||
"noImplicitThis": false,
|
||||
"alwaysStrict": true,
|
||||
"sourceMap": true,
|
||||
"outDir": "./build",
|
||||
"outDir": "./",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"pretty": true,
|
||||
|
||||
Reference in New Issue
Block a user