mirror of https://github.com/certd/certd
feat: plugin-huawei
parent
d602df4c70
commit
003ea9310b
|
@ -11,7 +11,7 @@
|
|||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/acme-client": "^0.3.0",
|
||||
"@certd/acme-client": "workspace:^0.3.0",
|
||||
"axios": "^0.21.1",
|
||||
"dayjs": "^1.11.6",
|
||||
"lodash": "^4.17.21",
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@certd/plugin-aliyun": "^0.3.0",
|
||||
"@certd/plugin-tencent": "^0.3.0",
|
||||
"@certd/plugin-host": "^0.3.0",
|
||||
"@certd/plugin-cert": "^0.3.0"
|
||||
"@certd/plugin-aliyun": "workspace:^0.3.0",
|
||||
"@certd/plugin-tencent": "workspace:^0.3.0",
|
||||
"@certd/plugin-host": "workspace:^0.3.0",
|
||||
"@certd/plugin-cert": "workspace:0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/pipeline": "^0.3.0",
|
||||
"@certd/pipeline": "workspace:0.3.0",
|
||||
"log4js": "^6.7.1",
|
||||
"@types/lodash": "^4.14.186",
|
||||
"vue-tsc": "^0.38.9",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { IAccessService } from "../../src/access/access-service";
|
||||
import { AbstractAccess, AliyunAccess } from "../../src";
|
||||
import { IAccessService } from "@certd/pipeline";
|
||||
import { AliyunAccess } from "@certd/plugin-aliyun";
|
||||
import { aliyunSecret } from "../user.secret";
|
||||
export class AccessServiceTest implements IAccessService {
|
||||
async getById(id: any): Promise<AbstractAccess> {
|
||||
async getById(id: any): Promise<any> {
|
||||
return {
|
||||
...aliyunSecret,
|
||||
} as AliyunAccess;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { ContextFactory } from "../../src/core/context";
|
||||
import { FileStorage } from "../../src/core/storage";
|
||||
import { ContextFactory, FileStorage, logger } from "@certd/pipeline";
|
||||
import { AccessServiceTest } from "./access-service-test";
|
||||
import { logger } from "../../src/utils/util.log";
|
||||
|
||||
const contextFactory = new ContextFactory(new FileStorage());
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ConcurrencyStrategy, NextStrategy, Pipeline, RunStrategy } from "../../src";
|
||||
import { ConcurrencyStrategy, NextStrategy, Pipeline, RunStrategy } from "@certd/pipeline";
|
||||
|
||||
let idIndex = 0;
|
||||
function generateId() {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { Executor, RunHistory } from "../../src";
|
||||
import { Executor, RunHistory, FileStorage } from "@certd/pipeline";
|
||||
import { pipeline } from "./pipeline.define";
|
||||
import { AccessServiceTest } from "./access-service-test";
|
||||
import { FileStorage } from "../../src/core/storage";
|
||||
import * as all from "../../src";
|
||||
describe("pipeline", function () {
|
||||
it("#pipeline", async function () {
|
||||
this.timeout(120000);
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { CertApplyPlugin } from "../../../src/plugin";
|
||||
import { pluginInitProps } from "../init.test";
|
||||
describe("CertApply", function () {
|
||||
it("#execute", async function () {
|
||||
this.timeout(120000);
|
||||
const plugin = new CertApplyPlugin();
|
||||
// @ts-ignore
|
||||
delete plugin.define;
|
||||
await plugin.doInit(pluginInitProps);
|
||||
const output = await plugin.execute({
|
||||
domains: ["*.docmirror.cn", "docmirror.cn"],
|
||||
email: "xiaojunnuo@qq.com",
|
||||
dnsProviderType: "aliyun",
|
||||
accessId: "111",
|
||||
forceUpdate: true,
|
||||
});
|
||||
const cert = output.cert;
|
||||
expect(plugin.getDefine().name).eq("CertApply");
|
||||
expect(cert.crt != null).eq(true);
|
||||
});
|
||||
});
|
|
@ -1,23 +0,0 @@
|
|||
import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { DeployCertToAliyunCDN } from "../../../src/plugin";
|
||||
import { pluginInitProps } from "../init.test";
|
||||
|
||||
describe("DeployToAliyunCDN", function () {
|
||||
it("#execute", async function () {
|
||||
this.timeout(120000);
|
||||
const plugin = new DeployCertToAliyunCDN();
|
||||
// @ts-ignore
|
||||
delete plugin.define;
|
||||
|
||||
await plugin.doInit(pluginInitProps);
|
||||
|
||||
const cert = await pluginInitProps.pipelineContext.get("cert");
|
||||
|
||||
await plugin.execute({
|
||||
cert,
|
||||
domainName: "certd-cdn-upload.docmirror.cn",
|
||||
});
|
||||
expect(plugin.getDefine().name).eq("DeployCertToAliyunCDN");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
// "no-unused-expressions": "off",
|
||||
"max-len": [0, 160, 2, { "ignoreUrls": true }]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
test/user.secret.ts
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"extension": ["ts"],
|
||||
"spec": "test/**/*.test.ts",
|
||||
"require": "ts-node/register"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printWidth": 160
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
# Vue 3 + TypeScript + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
|
||||
|
||||
## Type Support For `.vue` Imports in TS
|
||||
|
||||
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
|
||||
|
||||
1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
|
||||
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).
|
|
@ -0,0 +1 @@
|
|||
export * from "./src";
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"name": "@certd/plugin-hauwei",
|
||||
"private": true,
|
||||
"version": "0.3.0",
|
||||
"main": "./src/index.ts",
|
||||
"module": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"publishConfig": {
|
||||
"main": "./dist/plugin-aliyun.umd.js",
|
||||
"module": "./dist/plugin-aliyun.mjs",
|
||||
"types": "./dist/es/plugin-aliyun.d.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alicloud/cs20151215": "^3.0.3",
|
||||
"@alicloud/openapi-client": "^0.4.0",
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@certd/acme-client": "^0.3.0",
|
||||
"dayjs": "^1.11.6",
|
||||
"lodash": "^4.17.21",
|
||||
"node-forge": "^0.10.0",
|
||||
"@certd/pipeline": "^0.3.0",
|
||||
"@certd/plugin-util": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"log4js": "^6.7.1",
|
||||
"@types/lodash": "^4.14.186",
|
||||
"vue-tsc": "^0.38.9",
|
||||
"@alicloud/cs20151215": "^3.0.3",
|
||||
"@alicloud/openapi-client": "^0.4.0",
|
||||
"@alicloud/pop-core": "^1.7.10",
|
||||
"@midwayjs/core": "^3.0.0",
|
||||
"@midwayjs/decorator": "^3.0.0",
|
||||
"@types/chai": "^4.3.3",
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/node-forge": "^1.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.38.1",
|
||||
"@typescript-eslint/parser": "^5.38.1",
|
||||
"chai": "^4.3.6",
|
||||
"eslint": "^8.24.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"mocha": "^10.1.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.4",
|
||||
"vite": "^3.1.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { IsAccess, AccessInput } from "@certd/pipeline";
|
||||
|
||||
@IsAccess({
|
||||
name: "huawei",
|
||||
title: "华为云授权",
|
||||
desc: "",
|
||||
})
|
||||
export class HuaweiAccess {
|
||||
@AccessInput({
|
||||
title: "accessKeyId",
|
||||
component: {
|
||||
placeholder: "accessKeyId",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
accessKeyId = "";
|
||||
@AccessInput({
|
||||
title: "accessKeySecret",
|
||||
component: {
|
||||
placeholder: "accessKeySecret",
|
||||
},
|
||||
required: true,
|
||||
})
|
||||
accessKeySecret = "";
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from "./huawei-access";
|
|
@ -0,0 +1,114 @@
|
|||
import _ from "lodash";
|
||||
import { CreateRecordOptions, IDnsProvider, IsDnsProvider, RemoveRecordOptions } from "@certd/plugin-cert";
|
||||
import { Autowire, ILogger } from "@certd/pipeline";
|
||||
import { HuaweiAccess } from "../access";
|
||||
import { HuaweiYunClient } from "../lib/client";
|
||||
|
||||
@IsDnsProvider({
|
||||
name: "huawei",
|
||||
title: "华为云",
|
||||
desc: "华为云DNS解析提供商",
|
||||
accessType: "huawei",
|
||||
})
|
||||
export class HuaweiDnsProvider implements IDnsProvider {
|
||||
client: any;
|
||||
@Autowire()
|
||||
access!: HuaweiAccess;
|
||||
@Autowire()
|
||||
logger!: ILogger;
|
||||
endpoint = "https://domains-external.myhuaweicloud.com";
|
||||
async onInit() {
|
||||
const access: any = this.access;
|
||||
this.client = new HuaweiYunClient(access);
|
||||
}
|
||||
|
||||
async getDomainList() {
|
||||
const url = `${this.endpoint}/v2/domains`;
|
||||
const ret = await this.client.request({
|
||||
url,
|
||||
method: "GET",
|
||||
});
|
||||
return ret.domains;
|
||||
}
|
||||
|
||||
async matchDomain(dnsRecord: string) {
|
||||
const list = await this.getDomainList();
|
||||
let domain = null;
|
||||
for (const item of list) {
|
||||
if (_.endsWith(dnsRecord, item.DomainName)) {
|
||||
domain = item.DomainName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!domain) {
|
||||
throw new Error("can not find Domain ," + dnsRecord);
|
||||
}
|
||||
return domain;
|
||||
}
|
||||
|
||||
async getRecords(domain: string, rr: string, value: string) {
|
||||
const params: any = {
|
||||
RegionId: "cn-hangzhou",
|
||||
DomainName: domain,
|
||||
RRKeyWord: rr,
|
||||
ValueKeyWord: undefined,
|
||||
};
|
||||
if (value) {
|
||||
params.ValueKeyWord = value;
|
||||
}
|
||||
|
||||
const requestOption = {
|
||||
method: "POST",
|
||||
};
|
||||
|
||||
const ret = await this.client.request("DescribeDomainRecords", params, requestOption);
|
||||
return ret.DomainRecords.Record;
|
||||
}
|
||||
|
||||
async createRecord(options: CreateRecordOptions): Promise<any> {
|
||||
const { fullRecord, value, type } = options;
|
||||
this.logger.info("添加域名解析:", fullRecord, value);
|
||||
const domain = await this.matchDomain(fullRecord);
|
||||
const rr = fullRecord.replace("." + domain, "");
|
||||
|
||||
const params = {
|
||||
RegionId: "cn-hangzhou",
|
||||
DomainName: domain,
|
||||
RR: rr,
|
||||
Type: type,
|
||||
Value: value,
|
||||
// Line: 'oversea' // 海外
|
||||
};
|
||||
|
||||
const requestOption = {
|
||||
method: "POST",
|
||||
};
|
||||
|
||||
try {
|
||||
const ret = await this.client.request("AddDomainRecord", params, requestOption);
|
||||
this.logger.info("添加域名解析成功:", value, value, ret.RecordId);
|
||||
return ret.RecordId;
|
||||
} catch (e: any) {
|
||||
if (e.code === "DomainRecordDuplicate") {
|
||||
return;
|
||||
}
|
||||
this.logger.info("添加域名解析出错", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
async removeRecord(options: RemoveRecordOptions): Promise<any> {
|
||||
const { fullRecord, value, record } = options;
|
||||
const params = {
|
||||
RegionId: "cn-hangzhou",
|
||||
RecordId: record,
|
||||
};
|
||||
|
||||
const requestOption = {
|
||||
method: "POST",
|
||||
};
|
||||
|
||||
const ret = await this.client.request("DeleteDomainRecord", params, requestOption);
|
||||
this.logger.info("删除域名解析成功:", fullRecord, value, ret.RecordId);
|
||||
return ret.RecordId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
import "./huawei-dns-provider";
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./access";
|
||||
export * from "./dns-provider";
|
24
packages/plugins/plugin-huawei/src/lib/APIGW-javascript-sdk-2.0.5/licenses/license-crypto-js
vendored
Normal file
24
packages/plugins/plugin-huawei/src/lib/APIGW-javascript-sdk-2.0.5/licenses/license-crypto-js
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
# License
|
||||
|
||||
[The MIT License (MIT)](http://opensource.org/licenses/MIT)
|
||||
|
||||
Copyright (c) 2009-2013 Jeff Mott
|
||||
Copyright (c) 2013-2016 Evan Vosberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
20
packages/plugins/plugin-huawei/src/lib/APIGW-javascript-sdk-2.0.5/licenses/license-node
vendored
Normal file
20
packages/plugins/plugin-huawei/src/lib/APIGW-javascript-sdk-2.0.5/licenses/license-node
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
35
packages/plugins/plugin-huawei/src/lib/APIGW-javascript-sdk-2.0.5/node_demo.js
vendored
Normal file
35
packages/plugins/plugin-huawei/src/lib/APIGW-javascript-sdk-2.0.5/node_demo.js
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
var signer = require("./signer");
|
||||
var https = require("https");
|
||||
var sig = new signer.Signer();
|
||||
//Set the AK/SK to sign and authenticate the request.
|
||||
sig.Key = "QTWAOYTTINDUT2QVKYUC";
|
||||
sig.Secret = "MFyfvK41ba2giqM7**********KGpownRZlmVmHc";
|
||||
|
||||
//The following example shows how to set the request URL and parameters to query a VPC list.
|
||||
//Specify a request method, such as GET, PUT, POST, DELETE, HEAD, and PATCH.
|
||||
//Set request host.
|
||||
//Set request URI.
|
||||
//Set parameters for the request URL.
|
||||
var r = new signer.HttpRequest("GET", "endpoint.example.com/v1/77b6a44cba5143ab91d13ab9a8ff44fd/vpcs?limie=1");
|
||||
//Add header parameters, for example, x-domain-id for invoking a global service and x-project-id for invoking a project-level service.
|
||||
r.headers = { "Content-Type": "application/json" };
|
||||
//Add a body if you have specified the PUT or POST method. Special characters, such as the double quotation mark ("), contained in the body must be escaped.
|
||||
r.body = "";
|
||||
|
||||
var opt = sig.Sign(r);
|
||||
console.log(opt.headers["X-Sdk-Date"]);
|
||||
console.log(opt.headers["Authorization"]);
|
||||
|
||||
var req = https.request(opt, function (res) {
|
||||
console.log(res.statusCode);
|
||||
console.log("headers:", JSON.stringify(res.headers));
|
||||
res.on("data", function (chunk) {
|
||||
console.log(chunk.toString());
|
||||
});
|
||||
});
|
||||
|
||||
req.on("error", function (err) {
|
||||
console.log(err.message);
|
||||
});
|
||||
req.write(r.body);
|
||||
req.end();
|
501
packages/plugins/plugin-huawei/src/lib/APIGW-javascript-sdk-2.0.5/signer.js
vendored
Normal file
501
packages/plugins/plugin-huawei/src/lib/APIGW-javascript-sdk-2.0.5/signer.js
vendored
Normal file
|
@ -0,0 +1,501 @@
|
|||
// HWS API Gateway Signature
|
||||
(function (root, factory) {
|
||||
"use strict";
|
||||
|
||||
/*global define*/
|
||||
if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define(["CryptoJS"], function (CryptoJS) {
|
||||
var crypto_wrapper = {
|
||||
hmacsha256: function (keyByte, message) {
|
||||
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex);
|
||||
},
|
||||
HexEncodeSHA256Hash: function (body) {
|
||||
return CryptoJS.SHA256(body);
|
||||
},
|
||||
};
|
||||
return factory(crypto_wrapper);
|
||||
});
|
||||
} else if (typeof wx === "object") {
|
||||
// wechat
|
||||
var CryptoJS = require("./js/hmac-sha256.js");
|
||||
var crypto_wrapper = {
|
||||
hmacsha256: function (keyByte, message) {
|
||||
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex);
|
||||
},
|
||||
HexEncodeSHA256Hash: function (body) {
|
||||
return CryptoJS.SHA256(body);
|
||||
},
|
||||
};
|
||||
module.exports = factory(crypto_wrapper);
|
||||
} else if (typeof module === "object" && module.exports) {
|
||||
// Node
|
||||
var crypto = require("crypto");
|
||||
var crypto_wrapper = {
|
||||
hmacsha256: function (keyByte, message) {
|
||||
return crypto.createHmac("SHA256", keyByte).update(message).digest().toString("hex");
|
||||
},
|
||||
HexEncodeSHA256Hash: function (body) {
|
||||
return crypto.createHash("SHA256").update(body).digest().toString("hex");
|
||||
},
|
||||
};
|
||||
module.exports = factory(crypto_wrapper);
|
||||
} else {
|
||||
// Browser
|
||||
var CryptoJS = root.CryptoJS;
|
||||
var crypto_wrapper = {
|
||||
hmacsha256: function (keyByte, message) {
|
||||
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex);
|
||||
},
|
||||
HexEncodeSHA256Hash: function (body) {
|
||||
return CryptoJS.SHA256(body);
|
||||
},
|
||||
};
|
||||
root.signer = factory(crypto_wrapper);
|
||||
}
|
||||
})(this, function (crypto_wrapper) {
|
||||
"use strict";
|
||||
|
||||
var Algorithm = "SDK-HMAC-SHA256";
|
||||
var HeaderXDate = "X-Sdk-Date";
|
||||
var HeaderAuthorization = "Authorization";
|
||||
var HeaderContentSha256 = "x-sdk-content-sha256";
|
||||
|
||||
const hexTable = new Array(256);
|
||||
for (var i = 0; i < 256; ++i) hexTable[i] = "%" + ((i < 16 ? "0" : "") + i.toString(16)).toUpperCase();
|
||||
|
||||
const noEscape = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, // 0 - 15
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, // 16 - 31
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0, // 32 - 47
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, // 48 - 63
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1, // 64 - 79
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1, // 80 - 95
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1, // 96 - 111
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0, // 112 - 127
|
||||
];
|
||||
|
||||
// function urlEncode is based on https://github.com/nodejs/node/blob/master/lib/querystring.js
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
function urlEncode(str) {
|
||||
if (typeof str !== "string") {
|
||||
if (typeof str === "object") str = String(str);
|
||||
else str += "";
|
||||
}
|
||||
var out = "";
|
||||
var lastPos = 0;
|
||||
|
||||
for (var i = 0; i < str.length; ++i) {
|
||||
var c = str.charCodeAt(i);
|
||||
|
||||
// ASCII
|
||||
if (c < 0x80) {
|
||||
if (noEscape[c] === 1) continue;
|
||||
if (lastPos < i) out += str.slice(lastPos, i);
|
||||
lastPos = i + 1;
|
||||
out += hexTable[c];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lastPos < i) out += str.slice(lastPos, i);
|
||||
|
||||
// Multi-byte characters ...
|
||||
if (c < 0x800) {
|
||||
lastPos = i + 1;
|
||||
out += hexTable[0xc0 | (c >> 6)] + hexTable[0x80 | (c & 0x3f)];
|
||||
continue;
|
||||
}
|
||||
if (c < 0xd800 || c >= 0xe000) {
|
||||
lastPos = i + 1;
|
||||
out += hexTable[0xe0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3f)] + hexTable[0x80 | (c & 0x3f)];
|
||||
continue;
|
||||
}
|
||||
// Surrogate pair
|
||||
++i;
|
||||
|
||||
if (i >= str.length) throw new errors.URIError("ERR_INVALID_URI");
|
||||
|
||||
var c2 = str.charCodeAt(i) & 0x3ff;
|
||||
|
||||
lastPos = i + 1;
|
||||
c = 0x10000 + (((c & 0x3ff) << 10) | c2);
|
||||
out += hexTable[0xf0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3f)] + hexTable[0x80 | ((c >> 6) & 0x3f)] + hexTable[0x80 | (c & 0x3f)];
|
||||
}
|
||||
if (lastPos === 0) return str;
|
||||
if (lastPos < str.length) return out + str.slice(lastPos);
|
||||
return out;
|
||||
}
|
||||
|
||||
function HttpRequest(method, url, headers, body) {
|
||||
if (method === undefined) {
|
||||
this.method = "";
|
||||
} else {
|
||||
this.method = method;
|
||||
}
|
||||
if (url === undefined) {
|
||||
this.host = "";
|
||||
this.uri = "";
|
||||
this.query = {};
|
||||
} else {
|
||||
this.query = {};
|
||||
var host, path;
|
||||
var i = url.indexOf("://");
|
||||
if (i !== -1) {
|
||||
url = url.substr(i + 3);
|
||||
}
|
||||
var i = url.indexOf("?");
|
||||
if (i !== -1) {
|
||||
var query_str = url.substr(i + 1);
|
||||
url = url.substr(0, i);
|
||||
var spl = query_str.split("&");
|
||||
for (var i in spl) {
|
||||
var kv = spl[i];
|
||||
var index = kv.indexOf("=");
|
||||
var key, value;
|
||||
if (index >= 0) {
|
||||
key = kv.substr(0, index);
|
||||
value = kv.substr(index + 1);
|
||||
} else {
|
||||
key = kv;
|
||||
value = "";
|
||||
}
|
||||
if (key !== "") {
|
||||
key = decodeURI(key);
|
||||
value = decodeURI(value);
|
||||
if (this.query[key] === undefined) {
|
||||
this.query[key] = [value];
|
||||
} else {
|
||||
this.query[key].push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var i = url.indexOf("/");
|
||||
if (i === -1) {
|
||||
host = url;
|
||||
path = "/";
|
||||
} else {
|
||||
host = url.substr(0, i);
|
||||
path = url.substr(i);
|
||||
}
|
||||
this.host = host;
|
||||
this.uri = decodeURI(path);
|
||||
}
|
||||
if (headers === undefined) {
|
||||
this.headers = {};
|
||||
} else {
|
||||
this.headers = headers;
|
||||
}
|
||||
if (body === undefined) {
|
||||
this.body = "";
|
||||
} else {
|
||||
this.body = body;
|
||||
}
|
||||
}
|
||||
|
||||
function findHeader(r, header) {
|
||||
for (var k in r.headers) {
|
||||
if (k.toLowerCase() === header.toLowerCase()) {
|
||||
return r.headers[k];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Build a CanonicalRequest from a regular request string
|
||||
//
|
||||
// CanonicalRequest =
|
||||
// HTTPRequestMethod + '\n' +
|
||||
// CanonicalURI + '\n' +
|
||||
// CanonicalQueryString + '\n' +
|
||||
// CanonicalHeaders + '\n' +
|
||||
// SignedHeaders + '\n' +
|
||||
// HexEncode(Hash(RequestPayload))
|
||||
function CanonicalRequest(r, signedHeaders) {
|
||||
var hexencode = findHeader(r, HeaderContentSha256);
|
||||
if (hexencode === null) {
|
||||
var data = RequestPayload(r);
|
||||
hexencode = crypto_wrapper.HexEncodeSHA256Hash(data);
|
||||
}
|
||||
return (
|
||||
r.method +
|
||||
"\n" +
|
||||
CanonicalURI(r) +
|
||||
"\n" +
|
||||
CanonicalQueryString(r) +
|
||||
"\n" +
|
||||
CanonicalHeaders(r, signedHeaders) +
|
||||
"\n" +
|
||||
signedHeaders.join(";") +
|
||||
"\n" +
|
||||
hexencode
|
||||
);
|
||||
}
|
||||
|
||||
function CanonicalURI(r) {
|
||||
var pattens = r.uri.split("/");
|
||||
var uri = [];
|
||||
for (var k in pattens) {
|
||||
var v = pattens[k];
|
||||
uri.push(urlEncode(v));
|
||||
}
|
||||
var urlpath = uri.join("/");
|
||||
if (urlpath[urlpath.length - 1] !== "/") {
|
||||
urlpath = urlpath + "/";
|
||||
}
|
||||
//r.uri = urlpath
|
||||
return urlpath;
|
||||
}
|
||||
|
||||
function CanonicalQueryString(r) {
|
||||
var keys = [];
|
||||
for (var key in r.query) {
|
||||
keys.push(key);
|
||||
}
|
||||
keys.sort();
|
||||
var a = [];
|
||||
for (var i in keys) {
|
||||
var key = urlEncode(keys[i]);
|
||||
var value = r.query[keys[i]];
|
||||
if (Array.isArray(value)) {
|
||||
value.sort();
|
||||
for (var iv in value) {
|
||||
a.push(key + "=" + urlEncode(value[iv]));
|
||||
}
|
||||
} else {
|
||||
a.push(key + "=" + urlEncode(value));
|
||||
}
|
||||
}
|
||||
return a.join("&");
|
||||
}
|
||||
|
||||
function CanonicalHeaders(r, signedHeaders) {
|
||||
var headers = {};
|
||||
for (var key in r.headers) {
|
||||
headers[key.toLowerCase()] = r.headers[key];
|
||||
}
|
||||
var a = [];
|
||||
for (var i in signedHeaders) {
|
||||
var value = headers[signedHeaders[i]];
|
||||
a.push(signedHeaders[i] + ":" + value.trim());
|
||||
}
|
||||
return a.join("\n") + "\n";
|
||||
}
|
||||
|
||||
function SignedHeaders(r) {
|
||||
var a = [];
|
||||
for (var key in r.headers) {
|
||||
a.push(key.toLowerCase());
|
||||
}
|
||||
a.sort();
|
||||
return a;
|
||||
}
|
||||
|
||||
function RequestPayload(r) {
|
||||
return r.body;
|
||||
}
|
||||
|
||||
// Create a "String to Sign".
|
||||
function StringToSign(canonicalRequest, t) {
|
||||
var bytes = crypto_wrapper.HexEncodeSHA256Hash(canonicalRequest);
|
||||
return Algorithm + "\n" + t + "\n" + bytes;
|
||||
}
|
||||
|
||||
// Create the HWS Signature.
|
||||
function SignStringToSign(stringToSign, signingKey) {
|
||||
return crypto_wrapper.hmacsha256(signingKey, stringToSign);
|
||||
}
|
||||
|
||||
// Get the finalized value for the "Authorization" header. The signature
|
||||
// parameter is the output from SignStringToSign
|
||||
function AuthHeaderValue(signature, Key, signedHeaders) {
|
||||
return Algorithm + " Access=" + Key + ", SignedHeaders=" + signedHeaders.join(";") + ", Signature=" + signature;
|
||||
}
|
||||
|
||||
function twoChar(s) {
|
||||
if (s >= 10) {
|
||||
return "" + s;
|
||||
} else {
|
||||
return "0" + s;
|
||||
}
|
||||
}
|
||||
|
||||
function getTime() {
|
||||
var date = new Date();
|
||||
return (
|
||||
"" +
|
||||
date.getUTCFullYear() +
|
||||
twoChar(date.getUTCMonth() + 1) +
|
||||
twoChar(date.getUTCDate()) +
|
||||
"T" +
|
||||
twoChar(date.getUTCHours()) +
|
||||
twoChar(date.getUTCMinutes()) +
|
||||
twoChar(date.getUTCSeconds()) +
|
||||
"Z"
|
||||
);
|
||||
}
|
||||
|
||||
function Signer() {
|
||||
this.Key = "";
|
||||
this.Secret = "";
|
||||
}
|
||||
|
||||
Signer.prototype.Sign = function (r) {
|
||||
var headerTime = findHeader(r, HeaderXDate);
|
||||
if (headerTime === null) {
|
||||
headerTime = getTime();
|
||||
r.headers[HeaderXDate] = headerTime;
|
||||
}
|
||||
if (r.method !== "PUT" && r.method !== "PATCH" && r.method !== "POST") {
|
||||
r.body = "";
|
||||
}
|
||||
var queryString = CanonicalQueryString(r);
|
||||
if (queryString !== "") {
|
||||
queryString = "?" + queryString;
|
||||
}
|
||||
var options = {
|
||||
hostname: r.host,
|
||||
path: encodeURI(r.uri) + queryString,
|
||||
method: r.method,
|
||||
headers: r.headers,
|
||||
};
|
||||
if (findHeader(r, "host") === null) {
|
||||
r.headers.host = r.host;
|
||||
}
|
||||
var signedHeaders = SignedHeaders(r);
|
||||
var canonicalRequest = CanonicalRequest(r, signedHeaders);
|
||||
var stringToSign = StringToSign(canonicalRequest, headerTime);
|
||||
var signature = SignStringToSign(stringToSign, this.Secret);
|
||||
options.headers[HeaderAuthorization] = AuthHeaderValue(signature, this.Key, signedHeaders);
|
||||
return options;
|
||||
};
|
||||
return {
|
||||
HttpRequest: HttpRequest,
|
||||
Signer: Signer,
|
||||
urlEncode: urlEncode,
|
||||
findHeader: findHeader,
|
||||
SignedHeaders: SignedHeaders,
|
||||
CanonicalRequest: CanonicalRequest,
|
||||
StringToSign: StringToSign,
|
||||
};
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
var assert = require("assert");
|
||||
var signer = require('./signer')
|
||||
|
||||
var s = ""
|
||||
for (i = 0; i < 0x80; i++) {
|
||||
s = s + signer.urlEncode(String.fromCharCode(i))
|
||||
}
|
||||
console.log(s)
|
||||
assert.equal(s, "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F")
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// @ts-ignore
|
||||
import signer from "./signer";
|
||||
import https from "https";
|
||||
import { HuaweiAccess } from "../access";
|
||||
import { axios } from "@certd/acme-client";
|
||||
|
||||
export type ApiRequestOptions = {
|
||||
method: string;
|
||||
url: string;
|
||||
headers: any;
|
||||
body: any;
|
||||
};
|
||||
export class HuaweiYunClient {
|
||||
access: HuaweiAccess;
|
||||
constructor(access: HuaweiAccess) {
|
||||
this.access = access;
|
||||
}
|
||||
async request(options: ApiRequestOptions) {
|
||||
const sig = new signer.Signer();
|
||||
//Set the AK/SK to sign and authenticate the request.
|
||||
sig.Key = this.access.accessKeyId;
|
||||
sig.Secret = this.access.accessKeySecret;
|
||||
|
||||
//The following example shows how to set the request URL and parameters to query a VPC list.
|
||||
//Specify a request method, such as GET, PUT, POST, DELETE, HEAD, and PATCH.
|
||||
//Set request host.
|
||||
//Set request URI.
|
||||
//Set parameters for the request URL.
|
||||
const r = new signer.HttpRequest(options.method, options.url, options.headers, options.body);
|
||||
//Add header parameters, for example, x-domain-id for invoking a global service and x-project-id for invoking a project-level service.
|
||||
r.headers = { "Content-Type": "application/json" };
|
||||
//Add a body if you have specified the PUT or POST method. Special characters, such as the double quotation mark ("), contained in the body must be escaped.
|
||||
r.body = "";
|
||||
|
||||
const opt = sig.Sign(r);
|
||||
console.log("opt", opt);
|
||||
console.log(opt.headers["X-Sdk-Date"]);
|
||||
console.log(opt.headers["Authorization"]);
|
||||
const res = await axios.request(opt);
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,501 @@
|
|||
// HWS API Gateway Signature
|
||||
(function (root, factory) {
|
||||
"use strict";
|
||||
|
||||
/*global define*/
|
||||
if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define(["CryptoJS"], function (CryptoJS) {
|
||||
var crypto_wrapper = {
|
||||
hmacsha256: function (keyByte, message) {
|
||||
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex);
|
||||
},
|
||||
HexEncodeSHA256Hash: function (body) {
|
||||
return CryptoJS.SHA256(body);
|
||||
},
|
||||
};
|
||||
return factory(crypto_wrapper);
|
||||
});
|
||||
} else if (typeof wx === "object") {
|
||||
// wechat
|
||||
var CryptoJS = require("./js/hmac-sha256.js");
|
||||
var crypto_wrapper = {
|
||||
hmacsha256: function (keyByte, message) {
|
||||
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex);
|
||||
},
|
||||
HexEncodeSHA256Hash: function (body) {
|
||||
return CryptoJS.SHA256(body);
|
||||
},
|
||||
};
|
||||
module.exports = factory(crypto_wrapper);
|
||||
} else if (typeof module === "object" && module.exports) {
|
||||
// Node
|
||||
var crypto = require("crypto");
|
||||
var crypto_wrapper = {
|
||||
hmacsha256: function (keyByte, message) {
|
||||
return crypto.createHmac("SHA256", keyByte).update(message).digest().toString("hex");
|
||||
},
|
||||
HexEncodeSHA256Hash: function (body) {
|
||||
return crypto.createHash("SHA256").update(body).digest().toString("hex");
|
||||
},
|
||||
};
|
||||
module.exports = factory(crypto_wrapper);
|
||||
} else {
|
||||
// Browser
|
||||
var CryptoJS = root.CryptoJS;
|
||||
var crypto_wrapper = {
|
||||
hmacsha256: function (keyByte, message) {
|
||||
return CryptoJS.HmacSHA256(message, keyByte).toString(CryptoJS.enc.Hex);
|
||||
},
|
||||
HexEncodeSHA256Hash: function (body) {
|
||||
return CryptoJS.SHA256(body);
|
||||
},
|
||||
};
|
||||
root.signer = factory(crypto_wrapper);
|
||||
}
|
||||
})(this, function (crypto_wrapper) {
|
||||
"use strict";
|
||||
|
||||
var Algorithm = "SDK-HMAC-SHA256";
|
||||
var HeaderXDate = "X-Sdk-Date";
|
||||
var HeaderAuthorization = "Authorization";
|
||||
var HeaderContentSha256 = "x-sdk-content-sha256";
|
||||
|
||||
const hexTable = new Array(256);
|
||||
for (var i = 0; i < 256; ++i) hexTable[i] = "%" + ((i < 16 ? "0" : "") + i.toString(16)).toUpperCase();
|
||||
|
||||
const noEscape = [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, // 0 - 15
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, // 16 - 31
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0, // 32 - 47
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, // 48 - 63
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1, // 64 - 79
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1, // 80 - 95
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1, // 96 - 111
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0, // 112 - 127
|
||||
];
|
||||
|
||||
// function urlEncode is based on https://github.com/nodejs/node/blob/master/lib/querystring.js
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
function urlEncode(str) {
|
||||
if (typeof str !== "string") {
|
||||
if (typeof str === "object") str = String(str);
|
||||
else str += "";
|
||||
}
|
||||
var out = "";
|
||||
var lastPos = 0;
|
||||
|
||||
for (var i = 0; i < str.length; ++i) {
|
||||
var c = str.charCodeAt(i);
|
||||
|
||||
// ASCII
|
||||
if (c < 0x80) {
|
||||
if (noEscape[c] === 1) continue;
|
||||
if (lastPos < i) out += str.slice(lastPos, i);
|
||||
lastPos = i + 1;
|
||||
out += hexTable[c];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lastPos < i) out += str.slice(lastPos, i);
|
||||
|
||||
// Multi-byte characters ...
|
||||
if (c < 0x800) {
|
||||
lastPos = i + 1;
|
||||
out += hexTable[0xc0 | (c >> 6)] + hexTable[0x80 | (c & 0x3f)];
|
||||
continue;
|
||||
}
|
||||
if (c < 0xd800 || c >= 0xe000) {
|
||||
lastPos = i + 1;
|
||||
out += hexTable[0xe0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3f)] + hexTable[0x80 | (c & 0x3f)];
|
||||
continue;
|
||||
}
|
||||
// Surrogate pair
|
||||
++i;
|
||||
|
||||
if (i >= str.length) throw new errors.URIError("ERR_INVALID_URI");
|
||||
|
||||
var c2 = str.charCodeAt(i) & 0x3ff;
|
||||
|
||||
lastPos = i + 1;
|
||||
c = 0x10000 + (((c & 0x3ff) << 10) | c2);
|
||||
out += hexTable[0xf0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3f)] + hexTable[0x80 | ((c >> 6) & 0x3f)] + hexTable[0x80 | (c & 0x3f)];
|
||||
}
|
||||
if (lastPos === 0) return str;
|
||||
if (lastPos < str.length) return out + str.slice(lastPos);
|
||||
return out;
|
||||
}
|
||||
|
||||
function HttpRequest(method, url, headers, body) {
|
||||
if (method === undefined) {
|
||||
this.method = "";
|
||||
} else {
|
||||
this.method = method;
|
||||
}
|
||||
if (url === undefined) {
|
||||
this.host = "";
|
||||
this.uri = "";
|
||||
this.query = {};
|
||||
} else {
|
||||
this.query = {};
|
||||
var host, path;
|
||||
var i = url.indexOf("://");
|
||||
if (i !== -1) {
|
||||
url = url.substr(i + 3);
|
||||
}
|
||||
var i = url.indexOf("?");
|
||||
if (i !== -1) {
|
||||
var query_str = url.substr(i + 1);
|
||||
url = url.substr(0, i);
|
||||
var spl = query_str.split("&");
|
||||
for (var i in spl) {
|
||||
var kv = spl[i];
|
||||
var index = kv.indexOf("=");
|
||||
var key, value;
|
||||
if (index >= 0) {
|
||||
key = kv.substr(0, index);
|
||||
value = kv.substr(index + 1);
|
||||
} else {
|
||||
key = kv;
|
||||
value = "";
|
||||
}
|
||||
if (key !== "") {
|
||||
key = decodeURI(key);
|
||||
value = decodeURI(value);
|
||||
if (this.query[key] === undefined) {
|
||||
this.query[key] = [value];
|
||||
} else {
|
||||
this.query[key].push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var i = url.indexOf("/");
|
||||
if (i === -1) {
|
||||
host = url;
|
||||
path = "/";
|
||||
} else {
|
||||
host = url.substr(0, i);
|
||||
path = url.substr(i);
|
||||
}
|
||||
this.host = host;
|
||||
this.uri = decodeURI(path);
|
||||
}
|
||||
if (headers === undefined) {
|
||||
this.headers = {};
|
||||
} else {
|
||||
this.headers = headers;
|
||||
}
|
||||
if (body === undefined) {
|
||||
this.body = "";
|
||||
} else {
|
||||
this.body = body;
|
||||
}
|
||||
}
|
||||
|
||||
function findHeader(r, header) {
|
||||
for (var k in r.headers) {
|
||||
if (k.toLowerCase() === header.toLowerCase()) {
|
||||
return r.headers[k];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Build a CanonicalRequest from a regular request string
|
||||
//
|
||||
// CanonicalRequest =
|
||||
// HTTPRequestMethod + '\n' +
|
||||
// CanonicalURI + '\n' +
|
||||
// CanonicalQueryString + '\n' +
|
||||
// CanonicalHeaders + '\n' +
|
||||
// SignedHeaders + '\n' +
|
||||
// HexEncode(Hash(RequestPayload))
|
||||
function CanonicalRequest(r, signedHeaders) {
|
||||
var hexencode = findHeader(r, HeaderContentSha256);
|
||||
if (hexencode === null) {
|
||||
var data = RequestPayload(r);
|
||||
hexencode = crypto_wrapper.HexEncodeSHA256Hash(data);
|
||||
}
|
||||
return (
|
||||
r.method +
|
||||
"\n" +
|
||||
CanonicalURI(r) +
|
||||
"\n" +
|
||||
CanonicalQueryString(r) +
|
||||
"\n" +
|
||||
CanonicalHeaders(r, signedHeaders) +
|
||||
"\n" +
|
||||
signedHeaders.join(";") +
|
||||
"\n" +
|
||||
hexencode
|
||||
);
|
||||
}
|
||||
|
||||
function CanonicalURI(r) {
|
||||
var pattens = r.uri.split("/");
|
||||
var uri = [];
|
||||
for (var k in pattens) {
|
||||
var v = pattens[k];
|
||||
uri.push(urlEncode(v));
|
||||
}
|
||||
var urlpath = uri.join("/");
|
||||
if (urlpath[urlpath.length - 1] !== "/") {
|
||||
urlpath = urlpath + "/";
|
||||
}
|
||||
//r.uri = urlpath
|
||||
return urlpath;
|
||||
}
|
||||
|
||||
function CanonicalQueryString(r) {
|
||||
var keys = [];
|
||||
for (var key in r.query) {
|
||||
keys.push(key);
|
||||
}
|
||||
keys.sort();
|
||||
var a = [];
|
||||
for (var i in keys) {
|
||||
var key = urlEncode(keys[i]);
|
||||
var value = r.query[keys[i]];
|
||||
if (Array.isArray(value)) {
|
||||
value.sort();
|
||||
for (var iv in value) {
|
||||
a.push(key + "=" + urlEncode(value[iv]));
|
||||
}
|
||||
} else {
|
||||
a.push(key + "=" + urlEncode(value));
|
||||
}
|
||||
}
|
||||
return a.join("&");
|
||||
}
|
||||
|
||||
function CanonicalHeaders(r, signedHeaders) {
|
||||
var headers = {};
|
||||
for (var key in r.headers) {
|
||||
headers[key.toLowerCase()] = r.headers[key];
|
||||
}
|
||||
var a = [];
|
||||
for (var i in signedHeaders) {
|
||||
var value = headers[signedHeaders[i]];
|
||||
a.push(signedHeaders[i] + ":" + value.trim());
|
||||
}
|
||||
return a.join("\n") + "\n";
|
||||
}
|
||||
|
||||
function SignedHeaders(r) {
|
||||
var a = [];
|
||||
for (var key in r.headers) {
|
||||
a.push(key.toLowerCase());
|
||||
}
|
||||
a.sort();
|
||||
return a;
|
||||
}
|
||||
|
||||
function RequestPayload(r) {
|
||||
return r.body;
|
||||
}
|
||||
|
||||
// Create a "String to Sign".
|
||||
function StringToSign(canonicalRequest, t) {
|
||||
var bytes = crypto_wrapper.HexEncodeSHA256Hash(canonicalRequest);
|
||||
return Algorithm + "\n" + t + "\n" + bytes;
|
||||
}
|
||||
|
||||
// Create the HWS Signature.
|
||||
function SignStringToSign(stringToSign, signingKey) {
|
||||
return crypto_wrapper.hmacsha256(signingKey, stringToSign);
|
||||
}
|
||||
|
||||
// Get the finalized value for the "Authorization" header. The signature
|
||||
// parameter is the output from SignStringToSign
|
||||
function AuthHeaderValue(signature, Key, signedHeaders) {
|
||||
return Algorithm + " Access=" + Key + ", SignedHeaders=" + signedHeaders.join(";") + ", Signature=" + signature;
|
||||
}
|
||||
|
||||
function twoChar(s) {
|
||||
if (s >= 10) {
|
||||
return "" + s;
|
||||
} else {
|
||||
return "0" + s;
|
||||
}
|
||||
}
|
||||
|
||||
function getTime() {
|
||||
var date = new Date();
|
||||
return (
|
||||
"" +
|
||||
date.getUTCFullYear() +
|
||||
twoChar(date.getUTCMonth() + 1) +
|
||||
twoChar(date.getUTCDate()) +
|
||||
"T" +
|
||||
twoChar(date.getUTCHours()) +
|
||||
twoChar(date.getUTCMinutes()) +
|
||||
twoChar(date.getUTCSeconds()) +
|
||||
"Z"
|
||||
);
|
||||
}
|
||||
|
||||
function Signer() {
|
||||
this.Key = "";
|
||||
this.Secret = "";
|
||||
}
|
||||
|
||||
Signer.prototype.Sign = function (r) {
|
||||
var headerTime = findHeader(r, HeaderXDate);
|
||||
if (headerTime === null) {
|
||||
headerTime = getTime();
|
||||
r.headers[HeaderXDate] = headerTime;
|
||||
}
|
||||
if (r.method !== "PUT" && r.method !== "PATCH" && r.method !== "POST") {
|
||||
r.body = "";
|
||||
}
|
||||
var queryString = CanonicalQueryString(r);
|
||||
if (queryString !== "") {
|
||||
queryString = "?" + queryString;
|
||||
}
|
||||
var options = {
|
||||
hostname: r.host,
|
||||
path: encodeURI(r.uri) + queryString,
|
||||
method: r.method,
|
||||
headers: r.headers,
|
||||
};
|
||||
if (findHeader(r, "host") === null) {
|
||||
r.headers.host = r.host;
|
||||
}
|
||||
var signedHeaders = SignedHeaders(r);
|
||||
var canonicalRequest = CanonicalRequest(r, signedHeaders);
|
||||
var stringToSign = StringToSign(canonicalRequest, headerTime);
|
||||
var signature = SignStringToSign(stringToSign, this.Secret);
|
||||
options.headers[HeaderAuthorization] = AuthHeaderValue(signature, this.Key, signedHeaders);
|
||||
return options;
|
||||
};
|
||||
return {
|
||||
HttpRequest: HttpRequest,
|
||||
Signer: Signer,
|
||||
urlEncode: urlEncode,
|
||||
findHeader: findHeader,
|
||||
SignedHeaders: SignedHeaders,
|
||||
CanonicalRequest: CanonicalRequest,
|
||||
StringToSign: StringToSign,
|
||||
};
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
import dayjs from "dayjs";
|
||||
|
||||
export const ZoneOptions = [{ value: "cn-hangzhou" }];
|
||||
export function appendTimeSuffix(name: string) {
|
||||
if (name == null) {
|
||||
name = "certd";
|
||||
}
|
||||
return name + "-" + dayjs().format("YYYYMMDD-HHmmss");
|
||||
}
|
||||
|
||||
export function checkRet(ret: any) {
|
||||
if (ret.code != null) {
|
||||
throw new Error("执行失败:" + ret.Message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
export const fakeCrt = `-----BEGIN CERTIFICATE-----
|
||||
MIIFSTCCBDGgAwIBAgITAPoZZk/LhVIyXoic2NnJyxubezANBgkqhkiG9w0BAQsF
|
||||
ADAiMSAwHgYDVQQDDBdGYWtlIExFIEludGVybWVkaWF0ZSBYMTAeFw0yMDEyMTQx
|
||||
NjA1NTFaFw0yMTAzMTQxNjA1NTFaMBsxGTAXBgNVBAMMECouZG9jbWlycm9yLmNs
|
||||
dWIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC75tGrYjly+RpcZehQ
|
||||
my1EpaXElT4L60pINKV2YDKnBrcSSo1c6rO7nFh12eC/ju4WwYUep0RVmBDF8xD0
|
||||
I1Sd1uuDTQWP0UT1X9yqdXtjvxpUqoCHAzG633f3sJRFul7mDLuC9tRCuae9o7qP
|
||||
EZ827XOmjBR35dso9I2GEE4828J3YE3tSKtobZlM+30jozLEcsO0PTyM5mq5PPjP
|
||||
VI3fGLcEaBmLZf5ixz4XkcY9IAhyAMYf03cT2wRoYPBaDdXblgCYL6sFtIMbzl3M
|
||||
Di94PB8NyoNSsC2nmBdWi54wFOgBvY/4ljsX/q7X3EqlSvcA0/M6/c/J9kJ3eupv
|
||||
jV8nAgMBAAGjggJ9MIICeTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
|
||||
BQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFAkdTjSCV3KD
|
||||
x28sf98MrwVfyFYgMB8GA1UdIwQYMBaAFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHcG
|
||||
CCsGAQUFBwEBBGswaTAyBggrBgEFBQcwAYYmaHR0cDovL29jc3Auc3RnLWludC14
|
||||
MS5sZXRzZW5jcnlwdC5vcmcwMwYIKwYBBQUHMAKGJ2h0dHA6Ly9jZXJ0LnN0Zy1p
|
||||
bnQteDEubGV0c2VuY3J5cHQub3JnLzArBgNVHREEJDAighAqLmRvY21pcnJvci5j
|
||||
bHVigg5kb2NtaXJyb3IuY2x1YjBMBgNVHSAERTBDMAgGBmeBDAECATA3BgsrBgEE
|
||||
AYLfEwEBATAoMCYGCCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9y
|
||||
ZzCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB1ABboacHRlerXw/iXGuPwdgH3jOG2
|
||||
nTGoUhi2g38xqBUIAAABdmI3LM4AAAQDAEYwRAIgaiNqXSEq+sxp8eqlJXp/KFdO
|
||||
so5mT50MoRsLF8Inu0ACIDP46+ekng7I0BlmyIPmbqFcZgnZFVWLLCdLYijhVyOL
|
||||
AHcA3Zk0/KXnJIDJVmh9gTSZCEmySfe1adjHvKs/XMHzbmQAAAF2YjcuxwAABAMA
|
||||
SDBGAiEAxpeB8/w4YkHZ62nH20h128VtuTSmYDCnF7EK2fQyeZYCIQDbJlF2wehZ
|
||||
sF1BeE7qnYYqCTP0dYIrQ9HWtBa/MbGOKTANBgkqhkiG9w0BAQsFAAOCAQEAL2di
|
||||
HKh6XcZtGk0BFxJa51sCZ3MLu9+Zy90kCRD4ooP5x932WxVM25+LBRd+xSzx+TRL
|
||||
UVrlKp9GdMYX1JXL4Vf2NwzuFO3snPDe/qizD/3+D6yo8eKJ/LD82t5kLWAD2rto
|
||||
YfVSTKwfNIBBJwHUnjviBPJmheHHCKmz8Ct6/6QxFAeta9TAMn0sFeVCQnmAq7HL
|
||||
jrunq0tNHR/EKG0ITPLf+6P7MxbmpYNnq918766l0tKsW8oo8ZSGEwKU2LMaSiAa
|
||||
hasyl/2gMnYXjtKOjDcnR8oLpbrOg0qpVbynmJin1HP835oHPPAZ1gLsqYTTizNz
|
||||
AHxTaXliTVvS83dogw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw
|
||||
GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2
|
||||
MDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw
|
||||
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0
|
||||
8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym
|
||||
oLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0
|
||||
ZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN
|
||||
xDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56
|
||||
dhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9
|
||||
AgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw
|
||||
HQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0
|
||||
BggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu
|
||||
b3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu
|
||||
Y3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq
|
||||
hkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF
|
||||
UGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9
|
||||
AFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp
|
||||
DQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7
|
||||
IkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf
|
||||
zWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI
|
||||
PTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w
|
||||
SVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em
|
||||
2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0
|
||||
WzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt
|
||||
n5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=
|
||||
-----END CERTIFICATE-----`;
|
|
@ -0,0 +1,10 @@
|
|||
import { IAccessService } from "../../src/access/access-service";
|
||||
import { AbstractAccess, HuaweiAccess } from "../../src";
|
||||
import { aliyunSecret } from "../user.secret";
|
||||
export class AccessServiceTest implements IAccessService {
|
||||
async getById(id: any): Promise<AbstractAccess> {
|
||||
return {
|
||||
...aliyunSecret,
|
||||
} as HuaweiAccess;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import { ContextFactory } from "../../src/core/context";
|
||||
import { FileStorage } from "../../src/core/storage";
|
||||
import { AccessServiceTest } from "./access-service-test";
|
||||
import { logger } from "../../src/utils/util.log";
|
||||
|
||||
const contextFactory = new ContextFactory(new FileStorage());
|
||||
|
||||
const userContext = contextFactory.getContext("user", "test");
|
||||
const pipelineContext = contextFactory.getContext("pipeline", "test");
|
||||
export const pluginInitProps = {
|
||||
accessService: new AccessServiceTest(),
|
||||
pipelineContext: pipelineContext,
|
||||
userContext: userContext,
|
||||
logger: logger,
|
||||
};
|
|
@ -0,0 +1,66 @@
|
|||
import { ConcurrencyStrategy, NextStrategy, Pipeline, RunStrategy } from "../../src";
|
||||
|
||||
let idIndex = 0;
|
||||
function generateId() {
|
||||
idIndex++;
|
||||
return idIndex + "";
|
||||
}
|
||||
export const pipeline: Pipeline = {
|
||||
version: 1,
|
||||
id: generateId(),
|
||||
title: "测试管道",
|
||||
userId: 1,
|
||||
triggers: [],
|
||||
stages: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "证书申请阶段",
|
||||
concurrency: ConcurrencyStrategy.Serial,
|
||||
next: NextStrategy.AllSuccess,
|
||||
tasks: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "申请证书任务",
|
||||
steps: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "申请证书",
|
||||
type: "CertApply",
|
||||
input: {
|
||||
domains: ["*.docmirror.cn"],
|
||||
email: "xiaojunnuo@qq.com",
|
||||
dnsProviderType: "aliyun",
|
||||
accessId: "111",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: generateId(),
|
||||
title: "证书部署阶段",
|
||||
concurrency: ConcurrencyStrategy.Serial,
|
||||
next: NextStrategy.AllSuccess,
|
||||
tasks: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "测试输出参数任务",
|
||||
steps: [
|
||||
{
|
||||
id: generateId(),
|
||||
title: "输出参数(echo插件)",
|
||||
type: "EchoPlugin",
|
||||
input: {
|
||||
cert: "cert",
|
||||
},
|
||||
strategy: {
|
||||
runStrategy: RunStrategy.SkipWhenSucceed,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
//import { expect } from "chai";
|
||||
import "mocha";
|
||||
import { Executor, RunHistory } from "../../src";
|
||||
import { pipeline } from "./pipeline.define";
|
||||
import { AccessServiceTest } from "./access-service-test";
|
||||
import { FileStorage } from "../../src/core/storage";
|
||||
describe("pipeline", function () {
|
||||
it("#pipeline", async function () {
|
||||
this.timeout(120000);
|
||||
function onChanged(history: RunHistory) {
|
||||
console.log("changed:");
|
||||
}
|
||||
|
||||
const executor = new Executor({ userId: "test", pipeline, onChanged, accessService: new AccessServiceTest(), storage: new FileStorage() });
|
||||
await executor.run(1, "user");
|
||||
// expect(define.name).eq("EchoPlugin");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "Node",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"skipLibCheck": true,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue","test/**/*.ts"],
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { defineConfig } from "vite";
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [],
|
||||
build: {
|
||||
lib: {
|
||||
entry: "src/index.ts",
|
||||
name: "pipeline",
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ["vue", "lodash-es", "dayjs", "@fast-crud/fast-crud"],
|
||||
output: {
|
||||
// Provide global variables to use in the UMD build
|
||||
// for externalized deps
|
||||
globals: {
|
||||
vue: "Vue",
|
||||
"lodash-es": "_",
|
||||
dayjs: "dayjs",
|
||||
"@fast-crud/fast-crud": "FastCrud",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
Loading…
Reference in New Issue