mirror of
https://github.com/easychen/pushdeer.git
synced 2024-12-05 08:29:22 +08:00
实现了首页
This commit is contained in:
parent
f45975f051
commit
76c07bd6bb
27
quickapp/.gitignore
vendored
Normal file
27
quickapp/.gitignore
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
/build
|
||||
/sign
|
||||
|
||||
# sign
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw*
|
||||
.ide
|
||||
.quickapp.preview.json
|
1
quickapp/.npmrc
Normal file
1
quickapp/.npmrc
Normal file
@ -0,0 +1 @@
|
||||
registry="https://registry.npm.taobao.org"
|
6
quickapp/.prettierignore
Normal file
6
quickapp/.prettierignore
Normal file
@ -0,0 +1,6 @@
|
||||
package.json
|
||||
manifest.json
|
||||
README.md
|
||||
|
||||
# assets/js
|
||||
src/assets/js/*.js
|
5
quickapp/README.md
Normal file
5
quickapp/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# PushDeer-快应用 (开发中)
|
||||
|
||||
PushDeer 是一个开放源码的无 App 推送服务
|
||||
|
||||
这里是 PushDeer 的 `快应用` 端的源码
|
4399
quickapp/package-lock.json
generated
Normal file
4399
quickapp/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
58
quickapp/package.json
Normal file
58
quickapp/package.json
Normal file
@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "pushdeer",
|
||||
"version": "2.0.0",
|
||||
"description": "PushDeer开源版,可以自行架设的无APP推送服务",
|
||||
"scripts": {
|
||||
"start": "hap server --watch",
|
||||
"server": "hap server",
|
||||
"build": "hap build",
|
||||
"release": "hap release",
|
||||
"watch": "hap watch",
|
||||
"debug": "hap debug",
|
||||
"gen": "node ./scripts/gen/index.js",
|
||||
"precommit-msg": "echo '🚧 start pre-commit checks ...' && exit 0",
|
||||
"prettier": "node ./scripts/selfCloseInputTag.js && prettier --write \"src/**/*.{ux,js,json,less,scss,css,pcss,md,vue}\"",
|
||||
"prettier-watcher": "onchange '**/*.md' \"src/**/**/*.{ux,js,json,less,scss,css,pcss,md,vue}\" -- prettier --write {{changed}}"
|
||||
},
|
||||
"dependencies": {
|
||||
"apex-ui": "^1.9.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@types/quickapp": "npm:quickapp-interface@^1.0.0",
|
||||
"colors": "^1.4.0",
|
||||
"husky": "^7.0.1",
|
||||
"less": "^4.1.1",
|
||||
"less-loader": "^10.0.1",
|
||||
"lint-staged": "^11.0.1",
|
||||
"onchange": "^5.2.0",
|
||||
"prettier": "^2.3.2",
|
||||
"prettier-plugin-ux": "^0.3.0"
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"printWidth": 80,
|
||||
"proseWrap": "never",
|
||||
"tabWidth": 2
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "yarn run precommit-msg && lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/**.{ux,js,json,less,scss,css,pcss,md,vue}": [
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"keywords": [
|
||||
"快应用",
|
||||
"快应用示例",
|
||||
"快应用模版"
|
||||
],
|
||||
"browserslist": [
|
||||
"chrome 65"
|
||||
]
|
||||
}
|
87
quickapp/scripts/gen/index.js
Normal file
87
quickapp/scripts/gen/index.js
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @desc: gen script command,make a new page generated by one click.
|
||||
* @author: nicejade
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const colors = require('colors')
|
||||
|
||||
const newFolderName = process.argv[2]
|
||||
|
||||
String.prototype.firstUpperCase = function() {
|
||||
return this.replace(/\b(\w)/g, $1 => {
|
||||
return $1.toLowerCase()
|
||||
})
|
||||
}
|
||||
const resolve = dir => {
|
||||
return path.join(__dirname, '../..', dir)
|
||||
}
|
||||
|
||||
const successExecPrint = msg => {
|
||||
console.log(
|
||||
colors.green(`✓ `) +
|
||||
colors.cyan(`${msg} `) +
|
||||
colors.green('task has been successfully executed.')
|
||||
)
|
||||
}
|
||||
|
||||
function createNewPage(newFolderPath) {
|
||||
const mReg = new RegExp('@PAGE_CLASS_NAME', 'g')
|
||||
const pageContent = fs.readFileSync(`${__dirname}/template.ux`, 'UTF-8')
|
||||
const rootClassName = newFolderName
|
||||
.firstUpperCase()
|
||||
.replace(/([A-Z])/g, '-$1')
|
||||
.toLowerCase()
|
||||
const newContent = pageContent.replace(mReg, rootClassName)
|
||||
|
||||
fs.mkdirSync(newFolderPath, 0777)
|
||||
fs.writeFile(`${newFolderPath}/index.ux`, newContent, error => {
|
||||
if (error) throw `Something went wrong: ${error}`
|
||||
})
|
||||
successExecPrint('Create New Page')
|
||||
}
|
||||
|
||||
function saveRouter2Manifest() {
|
||||
const manifestPath = resolve('/src/manifest.json')
|
||||
let manifestConf = fs.readFileSync(manifestPath, 'UTF-8')
|
||||
manifestConf = JSON.parse(manifestConf)
|
||||
const routerPages = manifestConf.router.pages
|
||||
routerPages[`pages/${newFolderName}`] = {
|
||||
component: 'index'
|
||||
}
|
||||
manifestConf = JSON.stringify(manifestConf, null, 2)
|
||||
fs.writeFile(manifestPath, manifestConf, error => {
|
||||
if (error) throw `Something went wrong[@saveRouter2Manifest]: ${error}`
|
||||
})
|
||||
successExecPrint('Save Router Into Manifest')
|
||||
}
|
||||
|
||||
function main() {
|
||||
if (!newFolderName) {
|
||||
return console.warn(
|
||||
`⚠️ Please enter the name of the page you want to create.`.underline.red
|
||||
)
|
||||
}
|
||||
|
||||
const folderNameReg = /^[A-Z][[A-Za-z0-9]+$/
|
||||
if (!folderNameReg.test(newFolderName)) {
|
||||
return console.warn(
|
||||
`⚠️ Please enter the standard Folder name. Eg: XyzAbcde.`.underline.red
|
||||
)
|
||||
}
|
||||
|
||||
const newFolderPath = path.join(__dirname, `../../src/pages/${newFolderName}`)
|
||||
const isExist = fs.existsSync(newFolderPath)
|
||||
|
||||
if (isExist) {
|
||||
return console.warn(
|
||||
`⚠️ ${newFolderName} already exists in the /src/pages/ directory.`
|
||||
.underline.red
|
||||
)
|
||||
}
|
||||
createNewPage(newFolderPath)
|
||||
saveRouter2Manifest()
|
||||
}
|
||||
|
||||
main()
|
28
quickapp/scripts/gen/template.ux
Normal file
28
quickapp/scripts/gen/template.ux
Normal file
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<text class="title">{{ title }}</text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
private: {
|
||||
title: '欢迎体验快应用开发'
|
||||
},
|
||||
|
||||
onInit() {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import './../../assets/styles/style.less';
|
||||
|
||||
.wrapper {
|
||||
.flex-box-mixins(column, center, center);
|
||||
.title {
|
||||
font-size: 8 * @size-factor;
|
||||
text-align: center;
|
||||
color: @black;
|
||||
}
|
||||
}
|
||||
</style>
|
36
quickapp/scripts/selfCloseInputTag.js
Normal file
36
quickapp/scripts/selfCloseInputTag.js
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @file: selfCloseInputTag.js
|
||||
* @desc: 遍历指定目录下 .ux 文件,将其中 input 标签由 <input **></input> 转换为 <input ** />
|
||||
* @date: 2019-01-23
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const quickappCodePath = './src/'
|
||||
|
||||
const main = codePath => {
|
||||
const traversing = cpath => {
|
||||
const files = fs.readdirSync(cpath)
|
||||
files.forEach(fileName => {
|
||||
const fPath = path.join(cpath, fileName)
|
||||
const stats = fs.statSync(fPath)
|
||||
stats.isDirectory() && traversing(fPath)
|
||||
stats.isFile() && fPath.endsWith('.ux') && matchAndReplace(fPath)
|
||||
})
|
||||
}
|
||||
traversing(codePath)
|
||||
}
|
||||
|
||||
const matchAndReplace = path => {
|
||||
const pageContent = fs.readFileSync(path, 'UTF-8')
|
||||
const newContent = pageContent.replace(
|
||||
/(<)([\s]*?)(input\b[^\/]*?)>[\s\S]*?<\/input>/gm,
|
||||
'$1$3 />'
|
||||
)
|
||||
fs.writeFile(path, newContent, error => {
|
||||
if (error) throw `Something went wrong: ${error}`
|
||||
})
|
||||
}
|
||||
|
||||
main(quickappCodePath)
|
17
quickapp/src/app.ux
Normal file
17
quickapp/src/app.ux
Normal file
@ -0,0 +1,17 @@
|
||||
<script>
|
||||
/**
|
||||
* 应用级别的配置,供所有页面公用
|
||||
*/
|
||||
|
||||
const $utils = require('./helper/utils').default
|
||||
const $apis = require('./helper/apis').default
|
||||
|
||||
/* @desc: 注入方法至全局 global,以便页面调用 */
|
||||
const hook2global = global.__proto__ || global
|
||||
hook2global.$utils = $utils
|
||||
hook2global.$apis = $apis
|
||||
|
||||
export default {
|
||||
onCreate() {}
|
||||
}
|
||||
</script>
|
BIN
quickapp/src/assets/images/launch-logo.png
Normal file
BIN
quickapp/src/assets/images/launch-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
quickapp/src/assets/images/logo.png
Normal file
BIN
quickapp/src/assets/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
5
quickapp/src/assets/styles/mixins.less
Normal file
5
quickapp/src/assets/styles/mixins.less
Normal file
@ -0,0 +1,5 @@
|
||||
.flex-box-mixins (@column, @justify, @align) {
|
||||
flex-direction: @column;
|
||||
justify-content: @justify;
|
||||
align-items: @align;
|
||||
}
|
2
quickapp/src/assets/styles/style.less
Normal file
2
quickapp/src/assets/styles/style.less
Normal file
@ -0,0 +1,2 @@
|
||||
@import './variables.less';
|
||||
@import './mixins.less';
|
9
quickapp/src/assets/styles/variables.less
Normal file
9
quickapp/src/assets/styles/variables.less
Normal file
@ -0,0 +1,9 @@
|
||||
@brand: #09ba07;
|
||||
|
||||
@white: #ffffff;
|
||||
@black: #000000;
|
||||
@grey: #9393aa;
|
||||
@red: #fa0101;
|
||||
@green: #ffff00;
|
||||
|
||||
@size-factor: 5px;
|
90
quickapp/src/helper/ajax.js
Normal file
90
quickapp/src/helper/ajax.js
Normal file
@ -0,0 +1,90 @@
|
||||
/**
|
||||
* 封装了一些网络请求方法,方便通过 Promise 的形式请求接口
|
||||
*/
|
||||
import $fetch from '@system.fetch'
|
||||
import $utils from './utils'
|
||||
|
||||
const TIMEOUT = 20000
|
||||
|
||||
Promise.prototype.finally = function(callback) {
|
||||
const P = this.constructor
|
||||
return this.then(
|
||||
value => P.resolve(callback()).then(() => value),
|
||||
reason =>
|
||||
P.resolve(callback()).then(() => {
|
||||
throw reason
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用快应用 fetch 接口做网络请求
|
||||
* @param params
|
||||
*/
|
||||
function fetchPromise(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$fetch
|
||||
.fetch({
|
||||
url: params.url,
|
||||
method: params.method,
|
||||
data: params.data
|
||||
})
|
||||
.then(response => {
|
||||
const result = response.data
|
||||
const content = JSON.parse(result.data)
|
||||
/* @desc: 可跟具体不同业务接口数据,返回你所需要的部分,使得使用尽可能便捷 */
|
||||
content.success ? resolve(content.value) : resolve(content.message)
|
||||
})
|
||||
.catch((error, code) => {
|
||||
console.log(`🐛 request fail, code = ${code}`)
|
||||
reject(error)
|
||||
})
|
||||
.finally(() => {
|
||||
console.log(`✔️ request @${params.url} has been completed.`)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理网络请求,timeout 是网络请求超时之后返回,默认 20s 可自行修改
|
||||
* @param params
|
||||
*/
|
||||
function requestHandle(params, timeout = TIMEOUT) {
|
||||
try {
|
||||
return Promise.race([
|
||||
fetchPromise(params),
|
||||
new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
reject(new Error('网络状况不太好,再刷新一次?'))
|
||||
}, timeout)
|
||||
})
|
||||
])
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
post: function(url, params) {
|
||||
return requestHandle({
|
||||
method: 'post',
|
||||
url: url,
|
||||
data: params
|
||||
})
|
||||
},
|
||||
get: function(url, params) {
|
||||
return requestHandle({
|
||||
method: 'get',
|
||||
url: $utils.queryString(url, params)
|
||||
})
|
||||
},
|
||||
put: function(url, params) {
|
||||
return requestHandle({
|
||||
method: 'put',
|
||||
url: url,
|
||||
data: params
|
||||
})
|
||||
}
|
||||
// 如果,method 您需要更多类型,可自行添加更多方法;
|
||||
}
|
20
quickapp/src/helper/apis/example.js
Normal file
20
quickapp/src/helper/apis/example.js
Normal file
@ -0,0 +1,20 @@
|
||||
import $ajax from '../ajax'
|
||||
|
||||
/**
|
||||
* @desc 在实际开发中,您可以将 baseUrl 替换为您的请求地址前缀;
|
||||
*
|
||||
* 已将 $apis 挂载在 global,您可以通过如下方式,进行调用:
|
||||
* $apis.example.getApi().then().catch().finally()
|
||||
*
|
||||
* 备注:如果您不需要发起请求,删除 apis 目录,以及 app.ux 中引用即可;
|
||||
*/
|
||||
const baseUrl = 'https://api.exampel.com/'
|
||||
|
||||
export default {
|
||||
getApi(data) {
|
||||
return $ajax.get(`${baseUrl}your-project-api`, data)
|
||||
},
|
||||
postOtherApi(data) {
|
||||
return $ajax.post(`${baseUrl}your-project-api`, data)
|
||||
}
|
||||
}
|
14
quickapp/src/helper/apis/index.js
Normal file
14
quickapp/src/helper/apis/index.js
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* 导出 apis 下目录的所有接口
|
||||
*/
|
||||
const files = require.context('.', true, /\.js/)
|
||||
const modules = {}
|
||||
|
||||
files.keys().forEach(key => {
|
||||
if (key === './index.js') {
|
||||
return
|
||||
}
|
||||
modules[key.replace(/(^\.\/|\.js$)/g, '')] = files(key).default
|
||||
})
|
||||
|
||||
export default modules
|
29
quickapp/src/helper/utils.js
Normal file
29
quickapp/src/helper/utils.js
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 您可以将常用的方法、或系统 API,统一封装,暴露全局,以便各页面、组件调用,而无需 require / import.
|
||||
*/
|
||||
const prompt = require('@system.prompt')
|
||||
|
||||
/**
|
||||
* 拼接 url 和参数
|
||||
*/
|
||||
function queryString(url, query) {
|
||||
let str = []
|
||||
for (let key in query) {
|
||||
str.push(key + '=' + query[key])
|
||||
}
|
||||
let paramStr = str.join('&')
|
||||
return paramStr ? `${url}?${paramStr}` : url
|
||||
}
|
||||
|
||||
function showToast(message = '', duration = 0) {
|
||||
if (!message) return
|
||||
prompt.showToast({
|
||||
message: message,
|
||||
duration
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
showToast,
|
||||
queryString
|
||||
}
|
54
quickapp/src/manifest.json
Normal file
54
quickapp/src/manifest.json
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"package": "com.pushdeer.app",
|
||||
"name": "pushdeer",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": 1,
|
||||
"minPlatformVersion": 1070,
|
||||
"icon": "/assets/images/logo.png",
|
||||
"features": [
|
||||
{
|
||||
"name": "system.prompt"
|
||||
},
|
||||
{
|
||||
"name": "system.router"
|
||||
},
|
||||
{
|
||||
"name": "system.shortcut"
|
||||
},
|
||||
{
|
||||
"name": "system.fetch"
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
"origin": "*"
|
||||
}
|
||||
],
|
||||
"template/official": "demo-template",
|
||||
"config": {
|
||||
"logLevel": "debug"
|
||||
},
|
||||
"router": {
|
||||
"entry": "pages",
|
||||
"pages": {
|
||||
"pages": {
|
||||
"component": "index"
|
||||
},
|
||||
"pages/Home": {
|
||||
"component": "index"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"titleBarBackgroundColor": "#f2f2f2",
|
||||
"titleBarTextColor": "#414141",
|
||||
"pages": {
|
||||
"pages/Demo": {
|
||||
"titleBarText": "PushDeer"
|
||||
},
|
||||
"pages/DemoDetail": {
|
||||
"titleBarText": "详情页"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
57
quickapp/src/pages/Home/index.ux
Normal file
57
quickapp/src/pages/Home/index.ux
Normal file
@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<!-- template里只能有一个根节点 -->
|
||||
<div class="wrapper">
|
||||
<text class="title">{{ text }}</text>
|
||||
<text class="desc"
|
||||
>快应用是移动互联网新型应用生态,与手机系统深度整合,为用户提供更加场景化的体验。具备传统APP完整的应用体验,但无需安装、即点即用。
|
||||
</text>
|
||||
<text class="desc"
|
||||
>标准是由主流手机厂商组成的快应用联盟联合制定。其标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台,以平台化的生态模式对个人开发者和企业开发者全品类开放
|
||||
</text>
|
||||
<input
|
||||
class="btn"
|
||||
type="button"
|
||||
value="欢迎使用"
|
||||
onclick="onWelcomeBtnClick"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
private: {
|
||||
text: '快应用是什么?',
|
||||
},
|
||||
|
||||
onWelcomeBtnClick() {
|
||||
$utils.showToast('快应用:复杂生活的简单答案,让生活更顺畅')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import './../../assets/styles/style.less';
|
||||
|
||||
.wrapper {
|
||||
.flex-box-mixins(column, center, center);
|
||||
margin: 0 10 * @size-factor;
|
||||
.title {
|
||||
font-size: 8 * @size-factor;
|
||||
text-align: center;
|
||||
color: @black;
|
||||
}
|
||||
.desc {
|
||||
margin-top: 10 * @size-factor;
|
||||
color: @grey;
|
||||
}
|
||||
.btn {
|
||||
width: 90 * @size-factor;
|
||||
height: 16 * @size-factor;
|
||||
border-radius: 8 * @size-factor;
|
||||
background-color: @brand;
|
||||
color: @white;
|
||||
font-size: 30px;
|
||||
margin-top: 16 * @size-factor;
|
||||
}
|
||||
}
|
||||
</style>
|
68
quickapp/src/pages/index.ux
Normal file
68
quickapp/src/pages/index.ux
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
<template>
|
||||
<!-- template里只能有一个根节点 -->
|
||||
<div class="container">
|
||||
<div style="height: 50%">
|
||||
<img class="logo" src="/assets/images/launch-logo.png" />
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<input
|
||||
class="btn-wx"
|
||||
type="button"
|
||||
title="mn"
|
||||
value="Sign in with WeChat"
|
||||
onclick="onSignWxBtnClick"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import router from '@system.router'
|
||||
|
||||
export default {
|
||||
// 页面级组件的数据模型,影响传入数据的覆盖机制:private内定义的属性不允许被覆盖
|
||||
private: {
|
||||
title: '欢迎体验快应用开发',
|
||||
},
|
||||
|
||||
onSignWxBtnClick() {
|
||||
router.push({
|
||||
uri: '/pages/Home',
|
||||
})
|
||||
},
|
||||
|
||||
onInit() {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.container {
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
margin: 0 auto;
|
||||
|
||||
input {
|
||||
margin: 16px 0;
|
||||
padding: 24px;
|
||||
border-width: 3px;
|
||||
border-radius: 8px;
|
||||
background-color: transparent;
|
||||
font-size: 32px;
|
||||
}
|
||||
.btn-wx {
|
||||
color: #296c05;
|
||||
border-color: #296c05;
|
||||
}
|
||||
}
|
||||
</style>
|
3
quickapp/src/sitemap.json
Normal file
3
quickapp/src/sitemap.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"rules": [{ "rule": "enable", "page": "*" }]
|
||||
}
|
1660
quickapp/yarn.lock
Normal file
1660
quickapp/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user