1 | ;
|
2 | /*
|
3 | 本测试用于对华为原子化服务的配置文件ability.xml进行校验。
|
4 | ability.xml所需声明内容包括:
|
5 | 1、ability用于声明应用内服务,intent属性用于叫起该服务;
|
6 | 2、display为可选项,用于声明服务页面展示信息;
|
7 | 3、service用于声明提供对应服务的页面;
|
8 | 4、parameter用于声明启动服务所需要的参数信息。
|
9 |
|
10 | 文件格式样式举例如下:
|
11 | *******************************************************************************************************************
|
12 | <?xml version="1.0" encoding="utf-8"?>
|
13 | <aml version="1"
|
14 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ability.xsd">
|
15 | <ability intent="ability.intent.ORDER_MOVIE">
|
16 | <display name="电影票预定" icon="Common/ticket.png" description="电影票预定"/>
|
17 | <service link="hap://app/com.huawei.www/movie/order">
|
18 | <parameter linkParameter="movieName" intentParameter="movieName" testValue="狮子王" urlEncoding="false"/>
|
19 | </service>
|
20 | </ability>
|
21 | <ability intent="ability.intents.ORDER_TAXI">
|
22 | <display name="打车" icon="Common/taxi.png" description="打车"/>
|
23 | <service link="hap://app/com.huawei.www/taxi/order">
|
24 | <parameter linkParameter="dstLocation" intentParameter="dstLocation" testValue="南京站" urlEncoding="false"/>
|
25 | </service>
|
26 | </ability>
|
27 | </aml>
|
28 | ******************************************************************************************************************
|
29 |
|
30 | 详细配置规范请参考华为开发者网站:developer.huawei.com
|
31 | */
|
32 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
33 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
34 | return new (P || (P = Promise))(function (resolve, reject) {
|
35 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
36 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
37 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
38 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
39 | });
|
40 | };
|
41 | Object.defineProperty(exports, "__esModule", { value: true });
|
42 | const helper_1 = require("@tarojs/helper");
|
43 | const fs = require("fs-extra");
|
44 | const _ = require("lodash/fp");
|
45 | const path = require("path");
|
46 | const xml2js = require('xml2js');
|
47 | const ABILITYXML = ['ability.xml'];
|
48 | function default_1({ appPath }) {
|
49 | return __awaiter(this, void 0, void 0, function* () {
|
50 | const PROJECT_PACKAGE_PATH = path.join(appPath, 'package.json');
|
51 | const PROJECT_FOLDER_FILES = fs.readdirSync('./');
|
52 | if (!fs.existsSync(PROJECT_PACKAGE_PATH)) {
|
53 | console.log(helper_1.chalk.red(`找不到${PROJECT_PACKAGE_PATH},请确定当前目录是Taro项目根目录!`));
|
54 | process.exit(1);
|
55 | }
|
56 | const inProjectFolder = filenames => _.intersectionBy(_.toLower, PROJECT_FOLDER_FILES, filenames).length > 0;
|
57 | const hasAbilityXML = inProjectFolder(ABILITYXML);
|
58 | const errorLines = [];
|
59 | if (!hasAbilityXML) {
|
60 | errorLines.push({
|
61 | desc: '没有检查到 ability.xml, 编写 ability.xml可以让其他应用方便地叫起应用内服务',
|
62 | valid: true
|
63 | });
|
64 | }
|
65 | else {
|
66 | const PROJECT_ABILITY_FILE_PATH = path.join(appPath, 'ability.xml');
|
67 | const data = fs.readFileSync(PROJECT_ABILITY_FILE_PATH);
|
68 | xml2js.parseString(data, function (err, result) {
|
69 | // 解析ability.xml配置文件
|
70 | if (err) {
|
71 | errorLines.push({
|
72 | desc: 'ability.xml 解析错误,请检查文件格式!',
|
73 | valid: true
|
74 | });
|
75 | }
|
76 | else {
|
77 | // 检查ability配置
|
78 | const abilities = result.aml.ability;
|
79 | if (abilities == null) {
|
80 | errorLines.push({
|
81 | desc: '没有发现 ability声明, 请检查是否定义完整',
|
82 | valid: true
|
83 | });
|
84 | }
|
85 | else {
|
86 | // 检查intent声明合法性
|
87 | const intentRegex = /ability.intent.[0-9A-Z_]+$/; // intent匹配规则
|
88 | const parameterRegex = /^[A-Za-z0-9_]+$/; // parameter匹配规则
|
89 | for (const x in abilities) {
|
90 | const abilityIndex = parseInt(x) + 1;
|
91 | // 检查intent声明
|
92 | if (!intentRegex.test(abilities[x].$.intent)) {
|
93 | errorLines.push({
|
94 | desc: '第' + abilityIndex + '个ability的intent格式错误',
|
95 | valid: true,
|
96 | solution: 'intent 必须声明为格式为ability.intent.xxx的字符串,xxx可以包含数字,大写字母和下划线'
|
97 | });
|
98 | }
|
99 | // 检查service的parameter声明合法性
|
100 | const services = abilities[x].service;
|
101 | if (services == null) {
|
102 | errorLines.push({
|
103 | desc: '第' + abilityIndex + '个ability没有发现 service声明, 请检查是否定义完整',
|
104 | valid: true
|
105 | });
|
106 | }
|
107 | else {
|
108 | for (const y in services) {
|
109 | const serviceIndex = parseInt(y) + 1;
|
110 | // 校验linkParameter
|
111 | if (!parameterRegex.test(services[y].parameter[0].$.linkParameter)) {
|
112 | errorLines.push({
|
113 | desc: '第' + abilityIndex + '个ability的第' + serviceIndex + '个service linkParameter 格式错误',
|
114 | valid: true,
|
115 | solution: 'linkParameter 只能包含数字,大写字母,小写字母和下划线'
|
116 | });
|
117 | }
|
118 | // 校验intentParameter
|
119 | if (!parameterRegex.test(services[y].parameter[0].$.intentParameter)) {
|
120 | errorLines.push({
|
121 | desc: '第' + abilityIndex + '个ability的第' + serviceIndex + '个service intentParameter 格式错误',
|
122 | valid: true,
|
123 | solution: 'intentParameter 只能包含数字,大写字母,小写字母和下划线'
|
124 | });
|
125 | }
|
126 | }
|
127 | }
|
128 | }
|
129 | }
|
130 | }
|
131 | });
|
132 | }
|
133 | return {
|
134 | desc: '检查原子化服务规范',
|
135 | lines: errorLines
|
136 | };
|
137 | });
|
138 | }
|
139 | exports.default = default_1;
|
140 | //# sourceMappingURL=abilityXMLValidator.js.map |
\ | No newline at end of file |