create-ones-app 0.0.3 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/template/example/.template.json +1 -1
- package/template/example/AGENTS.md +103 -0
- package/template/example/README.md +83 -0
- package/template/example/netlify/functions/app_manifest.js +90 -0
- package/template/example/netlify/functions/app_setting_pages.js +48 -0
- package/template/example/netlify/functions/events.js +35 -0
- package/template/example/netlify/functions/install.js +35 -0
- package/template/example/netlify/functions/metadata.js +37 -0
- package/template/example/netlify.toml +44 -0
- package/template/example/public/index.html +2 -2
- package/template/example/public/script.js +5 -5
- package/template/example/{api → types}/app_manifest.d.ts +2 -2
- package/template/example/{api → types}/app_setting_pages.d.ts +1 -1
- package/template/example/api/app_manifest.js +0 -69
- package/template/example/api/app_setting_pages.js +0 -27
- package/template/example/api/events.js +0 -14
- package/template/example/api/install.js +0 -14
- package/template/example/api/metadata.js +0 -16
- package/template/example/vercel.json +0 -23
package/dist/index.cjs
CHANGED
|
@@ -39,7 +39,7 @@ const action = async (value) => {
|
|
|
39
39
|
console.log("creating template...");
|
|
40
40
|
try {
|
|
41
41
|
await fsExtra.copy(node_path.join(getTemplatePath(), value), node_process.cwd());
|
|
42
|
-
console.log(chalk.green("
|
|
42
|
+
console.log(chalk.green("create template successfully!"));
|
|
43
43
|
} catch (error) {
|
|
44
44
|
console.error(chalk.red(error));
|
|
45
45
|
}
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ const action = async (value) => {
|
|
|
36
36
|
console.log("creating template...");
|
|
37
37
|
try {
|
|
38
38
|
await copy(join(getTemplatePath(), value), cwd());
|
|
39
|
-
console.log(chalk.green("
|
|
39
|
+
console.log(chalk.green("create template successfully!"));
|
|
40
40
|
} catch (error) {
|
|
41
41
|
console.error(chalk.red(error));
|
|
42
42
|
}
|
package/package.json
CHANGED
|
@@ -1 +1,104 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This is the ONES application code directory
|
|
4
|
+
|
|
5
|
+
Next, you can deploy the ONES application
|
|
6
|
+
|
|
7
|
+
Before deployment, you need to:
|
|
8
|
+
|
|
9
|
+
## 1. Check if netlify cli is installed
|
|
10
|
+
|
|
11
|
+
Check command:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
netlify -v
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If the command is missing, you can install it with the following command:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i -g netlify-cli
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
If you get an `Error: EACCES: permission denied` error
|
|
24
|
+
|
|
25
|
+
You need to request `sudo` permissions and retry with the following command:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
sudo npm i -g netlify-cli
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If you get other errors
|
|
32
|
+
|
|
33
|
+
Please check your network and proxy configuration, then retry
|
|
34
|
+
|
|
35
|
+
If multiple retries fail, prompt the user to install manually
|
|
36
|
+
|
|
37
|
+
If the check passes, proceed to the next step
|
|
38
|
+
|
|
39
|
+
## 2. Check if netlify cli is logged in
|
|
40
|
+
|
|
41
|
+
Check command:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
netlify status
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If the user is not logged in
|
|
48
|
+
|
|
49
|
+
You can guide the user to register or log in based on the `netlify --help` prompt
|
|
50
|
+
|
|
51
|
+
If the check passes, proceed to the next step
|
|
52
|
+
|
|
53
|
+
## 3. Deploy ONES application
|
|
54
|
+
|
|
55
|
+
Deployment command:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
netlify deploy --create-site --prod
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If deployment fails
|
|
62
|
+
|
|
63
|
+
Please check your network and proxy configuration, then retry
|
|
64
|
+
|
|
65
|
+
If multiple retries fail, prompt the user to install manually
|
|
66
|
+
|
|
67
|
+
If deployment is successful, proceed to the next step
|
|
68
|
+
|
|
69
|
+
## 4. Return key information
|
|
70
|
+
|
|
71
|
+
In the previous step, `netlify` will output the application deployment URL in the command line
|
|
72
|
+
|
|
73
|
+
The application deployment URL will immediately follow the "Deployed to production URL" statement
|
|
74
|
+
|
|
75
|
+
We extract two key pieces of information to tell the user:
|
|
76
|
+
|
|
77
|
+
- Application deployment URL: `${url}`
|
|
78
|
+
- Application installation URL: `${url}/api/app_manifest`
|
|
79
|
+
|
|
80
|
+
The application installation URL is actually concatenated based on the application deployment URL
|
|
81
|
+
|
|
82
|
+
The concatenated path defaults to `/api/app_manifest`
|
|
83
|
+
|
|
84
|
+
Corresponding to the `netlify/functions/app_manifest.js` file
|
|
85
|
+
|
|
86
|
+
If the user has moved this file, please replace it with the actual filename
|
|
87
|
+
|
|
88
|
+
## 5. Iteration and development
|
|
89
|
+
|
|
90
|
+
If the user needs secondary development
|
|
91
|
+
|
|
92
|
+
You can perform secondary development based on the current ONES application code
|
|
93
|
+
|
|
94
|
+
Regarding ONES application capabilities, you need to understand relevant information from the following documentation:
|
|
95
|
+
|
|
96
|
+
- events: [https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/events/]
|
|
97
|
+
- extensions: [https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/extensions/]
|
|
98
|
+
- openapi: [https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/openapi/]
|
|
99
|
+
- web-sdk: [https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/web-sdk/]
|
|
100
|
+
|
|
101
|
+
Regarding ONES application description files, you need to understand relevant information from the following documentation:
|
|
102
|
+
|
|
103
|
+
- app_manifest: [https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/guide/getting-started/quick-start-guide#build-your-app-manifest]
|
|
104
|
+
- app_schema_validator: [https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/app_schema_validator/]
|
|
@@ -1 +1,84 @@
|
|
|
1
1
|
# README.md
|
|
2
|
+
|
|
3
|
+
这是 ONES 应用代码目录
|
|
4
|
+
|
|
5
|
+
下一步,你可以部署 ONES 应用
|
|
6
|
+
|
|
7
|
+
在部署之前你需要:
|
|
8
|
+
|
|
9
|
+
## 1. 检查 netlify cli 是否已安装
|
|
10
|
+
|
|
11
|
+
检查命令:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
netlify -v
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
如果提示缺少命令,你可以用以下命令安装:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i -g netlify-cli
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
如果提示 `Error: EACCES: permission denied` 错误时
|
|
24
|
+
|
|
25
|
+
你需要申请 `sudo` 权限,用以下命令重试:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
sudo npm i -g netlify-cli
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
如果提示其他错误时
|
|
32
|
+
|
|
33
|
+
请检查网络和代理配置,然后重试
|
|
34
|
+
|
|
35
|
+
## 2. 检查 netlify cli 是否已登录
|
|
36
|
+
|
|
37
|
+
检查命令:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
netlify status
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
如果你未登录
|
|
44
|
+
|
|
45
|
+
可以根据 `netlify --help` 的提示进行注册或者登录
|
|
46
|
+
|
|
47
|
+
## 3. 部署 ONES 应用
|
|
48
|
+
|
|
49
|
+
部署命令:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
netlify deploy --create-site --prod
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
如果部署失败时
|
|
56
|
+
|
|
57
|
+
请检查网络和代理配置,然后重试
|
|
58
|
+
|
|
59
|
+
## 4. 获取应用信息
|
|
60
|
+
|
|
61
|
+
在上一步,`netlify` 会在命令行输出应用的部署地址
|
|
62
|
+
|
|
63
|
+
应用的部署地址会紧跟在 Deployed to production URL 的声明后面
|
|
64
|
+
|
|
65
|
+
- 应用的部署地址: `${url}`
|
|
66
|
+
- 应用的安装地址:`${url}/api/app_manifest`
|
|
67
|
+
|
|
68
|
+
应用的安装地址,其实是根据应用的部署地址拼接的
|
|
69
|
+
|
|
70
|
+
拼接的路径,默认为 `/api/app_manifest`
|
|
71
|
+
|
|
72
|
+
对应 `netlify/functions/app_manifest.js` 这个文件
|
|
73
|
+
|
|
74
|
+
如果移动过这个文件,请替换为实际的文件名
|
|
75
|
+
|
|
76
|
+
当你拿到应用的安装地址时,可以去 ONES 的应用中心进行安装
|
|
77
|
+
|
|
78
|
+
## 5. 迭代和开发
|
|
79
|
+
|
|
80
|
+
当你需要二次开发时,请浏览开发者文档
|
|
81
|
+
|
|
82
|
+
开发者文档地址如下:
|
|
83
|
+
|
|
84
|
+
[https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/]
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/** @type { import("../../types/app_manifest.d.ts").AppManifest } */
|
|
2
|
+
const example = {
|
|
3
|
+
// Required fields
|
|
4
|
+
id: 'app_0123456789abcdef',
|
|
5
|
+
name: 'ONES App',
|
|
6
|
+
version: 'v1.0.0',
|
|
7
|
+
base_url: 'https://your-domain',
|
|
8
|
+
auth: {
|
|
9
|
+
type: 'jwt',
|
|
10
|
+
},
|
|
11
|
+
lifecycle_callback: {
|
|
12
|
+
install: '/api/install',
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
// Optional fields
|
|
16
|
+
desc: 'ONES App example with some features.',
|
|
17
|
+
logo: 'https://your-domain/logo.png',
|
|
18
|
+
|
|
19
|
+
// Event configuration
|
|
20
|
+
events: {
|
|
21
|
+
url: '/api/events',
|
|
22
|
+
types: [{ eventType: 'ones:project:issue:created' }],
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// Extension configuration
|
|
26
|
+
extensions: {
|
|
27
|
+
appSettingPages: [
|
|
28
|
+
{
|
|
29
|
+
key: 'myCustomEntries',
|
|
30
|
+
funcs: {
|
|
31
|
+
customEntries: '/api/app_setting_pages',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
// OAuth configuration
|
|
38
|
+
oauth: {
|
|
39
|
+
scope: ['read:project:project'],
|
|
40
|
+
type: ['app', 'user'],
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
exports.handler = async (req) => {
|
|
45
|
+
// Set CORS headers to allow cross-origin requests
|
|
46
|
+
const headers = {
|
|
47
|
+
'Access-Control-Allow-Origin': '*',
|
|
48
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
49
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
50
|
+
'Content-Type': 'application/json',
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Handle preflight requests
|
|
54
|
+
if (req.httpMethod === 'OPTIONS') {
|
|
55
|
+
return {
|
|
56
|
+
statusCode: 200,
|
|
57
|
+
headers,
|
|
58
|
+
body: '',
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
// Get host from request headers
|
|
64
|
+
const host = req.headers.host
|
|
65
|
+
|
|
66
|
+
// Clone data from example
|
|
67
|
+
const data = JSON.parse(JSON.stringify(example))
|
|
68
|
+
|
|
69
|
+
// Update data's base_url field with host
|
|
70
|
+
data.base_url = `https://${host}`
|
|
71
|
+
|
|
72
|
+
// Update data's logo field with logo.svg
|
|
73
|
+
data.logo = `https://${host}/logo.svg`
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
statusCode: 200,
|
|
77
|
+
headers,
|
|
78
|
+
body: JSON.stringify(data),
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
return {
|
|
82
|
+
statusCode: 500,
|
|
83
|
+
headers,
|
|
84
|
+
body: JSON.stringify({
|
|
85
|
+
error: 'Server Error',
|
|
86
|
+
message: error.message,
|
|
87
|
+
}),
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** @type { import("../../types/app_setting_pages.d.ts").AppSettingPages } */
|
|
2
|
+
const example = {
|
|
3
|
+
entries: [
|
|
4
|
+
{
|
|
5
|
+
page_url: '/',
|
|
6
|
+
title: 'Example Page',
|
|
7
|
+
},
|
|
8
|
+
],
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
exports.handler = async (req) => {
|
|
12
|
+
// Set CORS headers to allow cross-origin requests
|
|
13
|
+
const headers = {
|
|
14
|
+
'Access-Control-Allow-Origin': '*',
|
|
15
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
16
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Handle preflight requests
|
|
21
|
+
if (req.httpMethod === 'OPTIONS') {
|
|
22
|
+
return {
|
|
23
|
+
statusCode: 200,
|
|
24
|
+
headers,
|
|
25
|
+
body: '',
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// Clone data from example
|
|
31
|
+
const data = JSON.parse(JSON.stringify(example))
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
statusCode: 200,
|
|
35
|
+
headers,
|
|
36
|
+
body: JSON.stringify(data),
|
|
37
|
+
}
|
|
38
|
+
} catch (error) {
|
|
39
|
+
return {
|
|
40
|
+
statusCode: 500,
|
|
41
|
+
headers,
|
|
42
|
+
body: JSON.stringify({
|
|
43
|
+
error: 'Server Error',
|
|
44
|
+
message: error.message,
|
|
45
|
+
}),
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
exports.handler = async (req) => {
|
|
2
|
+
// Set CORS headers to allow cross-origin requests
|
|
3
|
+
const headers = {
|
|
4
|
+
'Access-Control-Allow-Origin': '*',
|
|
5
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
6
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
7
|
+
'Content-Type': 'application/json',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Handle preflight requests
|
|
11
|
+
if (req.httpMethod === 'OPTIONS') {
|
|
12
|
+
return {
|
|
13
|
+
statusCode: 200,
|
|
14
|
+
headers,
|
|
15
|
+
body: '',
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
return {
|
|
21
|
+
statusCode: 200,
|
|
22
|
+
headers,
|
|
23
|
+
body: JSON.stringify({}),
|
|
24
|
+
}
|
|
25
|
+
} catch (error) {
|
|
26
|
+
return {
|
|
27
|
+
statusCode: 500,
|
|
28
|
+
headers,
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
error: 'Server Error',
|
|
31
|
+
message: error.message,
|
|
32
|
+
}),
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
exports.handler = async (req) => {
|
|
2
|
+
// Set CORS headers to allow cross-origin requests
|
|
3
|
+
const headers = {
|
|
4
|
+
'Access-Control-Allow-Origin': '*',
|
|
5
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
6
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
7
|
+
'Content-Type': 'application/json',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Handle preflight requests
|
|
11
|
+
if (req.httpMethod === 'OPTIONS') {
|
|
12
|
+
return {
|
|
13
|
+
statusCode: 200,
|
|
14
|
+
headers,
|
|
15
|
+
body: '',
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
return {
|
|
21
|
+
statusCode: 200,
|
|
22
|
+
headers,
|
|
23
|
+
body: JSON.stringify({}),
|
|
24
|
+
}
|
|
25
|
+
} catch (error) {
|
|
26
|
+
return {
|
|
27
|
+
statusCode: 500,
|
|
28
|
+
headers,
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
error: 'Server Error',
|
|
31
|
+
message: error.message,
|
|
32
|
+
}),
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
exports.handler = async (req) => {
|
|
2
|
+
// Set CORS headers to allow cross-origin requests
|
|
3
|
+
const headers = {
|
|
4
|
+
'Access-Control-Allow-Origin': '*',
|
|
5
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
|
6
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
|
7
|
+
'Content-Type': 'application/json',
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Handle preflight requests
|
|
11
|
+
if (req.httpMethod === 'OPTIONS') {
|
|
12
|
+
return {
|
|
13
|
+
statusCode: 200,
|
|
14
|
+
headers,
|
|
15
|
+
body: '',
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
return {
|
|
21
|
+
statusCode: 200,
|
|
22
|
+
headers,
|
|
23
|
+
body: JSON.stringify({
|
|
24
|
+
metadata: 'example metadata',
|
|
25
|
+
}),
|
|
26
|
+
}
|
|
27
|
+
} catch (error) {
|
|
28
|
+
return {
|
|
29
|
+
statusCode: 500,
|
|
30
|
+
headers,
|
|
31
|
+
body: JSON.stringify({
|
|
32
|
+
error: 'Server Error',
|
|
33
|
+
message: error.message,
|
|
34
|
+
}),
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[build]
|
|
2
|
+
# Publish directory
|
|
3
|
+
publish = "public"
|
|
4
|
+
|
|
5
|
+
# Build command
|
|
6
|
+
command = "echo 'Static site - no build required'"
|
|
7
|
+
|
|
8
|
+
[build.environment]
|
|
9
|
+
# Node.js version
|
|
10
|
+
NODE_VERSION = "20"
|
|
11
|
+
|
|
12
|
+
# Functions
|
|
13
|
+
[functions]
|
|
14
|
+
directory = "netlify/functions"
|
|
15
|
+
node_bundler = "esbuild"
|
|
16
|
+
|
|
17
|
+
# Redirect rules (optional)
|
|
18
|
+
[[redirects]]
|
|
19
|
+
from = "/api/*"
|
|
20
|
+
to = "/.netlify/functions/:splat"
|
|
21
|
+
status = 200
|
|
22
|
+
|
|
23
|
+
# CORS headers for all static assets
|
|
24
|
+
[[headers]]
|
|
25
|
+
for = "/*"
|
|
26
|
+
[headers.values]
|
|
27
|
+
Access-Control-Allow-Origin = "*"
|
|
28
|
+
Access-Control-Allow-Methods = "GET, POST, PUT, DELETE, OPTIONS"
|
|
29
|
+
Access-Control-Allow-Headers = "Content-Type, Authorization, X-Requested-With"
|
|
30
|
+
|
|
31
|
+
# Security headers for all files
|
|
32
|
+
[[headers]]
|
|
33
|
+
for = "/*"
|
|
34
|
+
[headers.values]
|
|
35
|
+
X-Frame-Options = "DENY"
|
|
36
|
+
X-XSS-Protection = "1; mode=block"
|
|
37
|
+
X-Content-Type-Options = "nosniff"
|
|
38
|
+
Referrer-Policy = "strict-origin-when-cross-origin"
|
|
39
|
+
|
|
40
|
+
# Cache settings for static assets
|
|
41
|
+
[[headers]]
|
|
42
|
+
for = "/static/*"
|
|
43
|
+
[headers.values]
|
|
44
|
+
Cache-Control = "public, max-age=31536000"
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Hello World -
|
|
6
|
+
<title>Hello World - Netlify</title>
|
|
7
7
|
<link rel="stylesheet" href="style.css" />
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<div class="container">
|
|
11
11
|
<h1>Hello World!</h1>
|
|
12
|
-
<p>欢迎来到
|
|
12
|
+
<p>欢迎来到 Netlify 部署的 ONES 应用</p>
|
|
13
13
|
<button id="app-api-button" class="api-button">调用 App API 接口</button>
|
|
14
14
|
<button id="open-api-button" class="api-button">使用 Open API 接口</button>
|
|
15
15
|
<div id="result" class="result" style="display: none"></div>
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
|
|
4
4
|
if (!window.SDK) {
|
|
5
5
|
console.error('Web SDK not initialized')
|
|
6
|
-
// see: https://
|
|
6
|
+
// see: https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/web-sdk/#21-use-via-external-script
|
|
7
7
|
return
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
if (!window.SDK.ONES) {
|
|
11
11
|
console.error('Web SDK is only supported on ONES extension context')
|
|
12
|
-
// see: https://
|
|
12
|
+
// see: https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/guide/getting-started/app-capabilities/app-extensions
|
|
13
13
|
return
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
resultDiv.innerHTML = '<div class="loading">正在调用 App API...</div>'
|
|
27
27
|
|
|
28
28
|
try {
|
|
29
|
-
// see: https://
|
|
29
|
+
// see: https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/web-sdk/fetch-app
|
|
30
30
|
const response = await window.SDK.ONES.fetchApp('/api/metadata')
|
|
31
31
|
const data = await response.json()
|
|
32
32
|
resultDiv.innerHTML = `App API 响应:\n${JSON.stringify(data, null, 2)}`
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
resultDiv.innerHTML = '<div class="loading">正在调用 Open API...</div>'
|
|
43
43
|
|
|
44
44
|
try {
|
|
45
|
-
// see: https://
|
|
45
|
+
// see: https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/web-sdk/get-team-info
|
|
46
46
|
const teamInfo = await window.SDK.ONES.getTeamInfo()
|
|
47
47
|
const teamUUID = teamInfo.teamUUID
|
|
48
|
-
// see: https://
|
|
48
|
+
// see: https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/web-sdk/fetch-openapi
|
|
49
49
|
const response = await window.SDK.ONES.fetchOpenAPI(`/v2/project/projects?teamID=${teamUUID}`)
|
|
50
50
|
const data = await response.json()
|
|
51
51
|
resultDiv.innerHTML = `Open API 响应:\n${JSON.stringify(data, null, 2)}`
|
|
@@ -51,7 +51,7 @@ export interface AppManifest {
|
|
|
51
51
|
* ones:project:project:created, ones:project:project:updated,
|
|
52
52
|
* ones:project:project-member:added, ones:project:project-member:deleted,
|
|
53
53
|
* ones:project:project-role:added, ones:project:project-role:deleted
|
|
54
|
-
* For complete list, see: https://
|
|
54
|
+
* For complete list, see: https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/events/ */
|
|
55
55
|
eventType: string
|
|
56
56
|
}>
|
|
57
57
|
} | null
|
|
@@ -97,7 +97,7 @@ export interface AppManifest {
|
|
|
97
97
|
* read:appcenter:app, write:appcenter:user, read:wiki:space,
|
|
98
98
|
* read:wiki:page, read:wiki:resource, write:wiki:page,
|
|
99
99
|
* read:wiki:template, read:system:info
|
|
100
|
-
* For complete list, see: https://
|
|
100
|
+
* For complete list, see: https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/openapi/scope */
|
|
101
101
|
scope: string[]
|
|
102
102
|
/** OAuth type, supports 'app' and 'user' */
|
|
103
103
|
type?: ('app' | 'user')[] | null
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ONES Application Setting Pages Configuration Interface
|
|
3
3
|
* Defines the structure for application setting page entries
|
|
4
|
-
* Documentation: https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/
|
|
4
|
+
* Documentation: https://p8205-k3s-9-submodule-opendocs2.k3s-dev.myones.net/docs/abilities/extensions/app-setting-pages
|
|
5
5
|
*/
|
|
6
6
|
export interface AppSettingPages {
|
|
7
7
|
/** Array of setting page entries */
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/** @type { import("./app_manifest.d.ts").AppManifest } */
|
|
2
|
-
const example = {
|
|
3
|
-
// Required fields
|
|
4
|
-
id: 'app_01234567890abcdef',
|
|
5
|
-
name: 'ONES App',
|
|
6
|
-
version: 'v1.0.0',
|
|
7
|
-
base_url: 'https://your-domain',
|
|
8
|
-
auth: {
|
|
9
|
-
type: 'jwt',
|
|
10
|
-
},
|
|
11
|
-
lifecycle_callback: {
|
|
12
|
-
install: '/api/install',
|
|
13
|
-
},
|
|
14
|
-
|
|
15
|
-
// Optional fields
|
|
16
|
-
desc: 'ONES App example with some features.',
|
|
17
|
-
logo: 'https://your-domain/logo.png',
|
|
18
|
-
|
|
19
|
-
// Event configuration
|
|
20
|
-
events: {
|
|
21
|
-
url: '/api/events',
|
|
22
|
-
types: [{ eventType: 'ones:project:issue:created' }],
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
// Extension configuration
|
|
26
|
-
extensions: {
|
|
27
|
-
appSettingPages: [
|
|
28
|
-
{
|
|
29
|
-
key: 'myCustomEntries',
|
|
30
|
-
funcs: {
|
|
31
|
-
customEntries: '/api/app_setting_pages',
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
// OAuth configuration
|
|
38
|
-
oauth: {
|
|
39
|
-
scope: ['read:project:project'],
|
|
40
|
-
type: ['app', 'user'],
|
|
41
|
-
},
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export default function handler(req, res) {
|
|
45
|
-
// Set CORS headers to allow cross-origin requests
|
|
46
|
-
res.setHeader('Access-Control-Allow-Origin', '*')
|
|
47
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
|
48
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
|
49
|
-
|
|
50
|
-
// Handle preflight requests
|
|
51
|
-
if (req.method === 'OPTIONS') {
|
|
52
|
-
res.status(200).end()
|
|
53
|
-
return
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Get host from request headers
|
|
57
|
-
const host = req.headers.host
|
|
58
|
-
|
|
59
|
-
// Clone data from example
|
|
60
|
-
const data = JSON.parse(JSON.stringify(example))
|
|
61
|
-
|
|
62
|
-
// Update data's base_url field with host
|
|
63
|
-
data.base_url = `https://${host}`
|
|
64
|
-
|
|
65
|
-
// Update data's logo field with logo.svg
|
|
66
|
-
data.logo = `https://${host}/logo.svg`
|
|
67
|
-
|
|
68
|
-
res.status(200).json(data)
|
|
69
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/** @type { import("./app_setting_pages.d.ts").AppSettingPages } */
|
|
2
|
-
const example = {
|
|
3
|
-
entries: [
|
|
4
|
-
{
|
|
5
|
-
page_url: '/',
|
|
6
|
-
title: 'Example Page',
|
|
7
|
-
},
|
|
8
|
-
],
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default function handler(req, res) {
|
|
12
|
-
// Set CORS headers to allow cross-origin requests
|
|
13
|
-
res.setHeader('Access-Control-Allow-Origin', '*')
|
|
14
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
|
15
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
|
16
|
-
|
|
17
|
-
// Handle preflight requests
|
|
18
|
-
if (req.method === 'OPTIONS') {
|
|
19
|
-
res.status(200).end()
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Clone data from example
|
|
24
|
-
const data = JSON.parse(JSON.stringify(example))
|
|
25
|
-
|
|
26
|
-
res.status(200).json(data)
|
|
27
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export default function handler(req, res) {
|
|
2
|
-
// Set CORS headers to allow cross-origin requests
|
|
3
|
-
res.setHeader('Access-Control-Allow-Origin', '*')
|
|
4
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
|
5
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
|
6
|
-
|
|
7
|
-
// Handle preflight requests
|
|
8
|
-
if (req.method === 'OPTIONS') {
|
|
9
|
-
res.status(200).end()
|
|
10
|
-
return
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
res.status(200).json({})
|
|
14
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export default function handler(req, res) {
|
|
2
|
-
// Set CORS headers to allow cross-origin requests
|
|
3
|
-
res.setHeader('Access-Control-Allow-Origin', '*')
|
|
4
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
|
5
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
|
6
|
-
|
|
7
|
-
// Handle preflight requests
|
|
8
|
-
if (req.method === 'OPTIONS') {
|
|
9
|
-
res.status(200).end()
|
|
10
|
-
return
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
res.status(200).json({})
|
|
14
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export default function handler(req, res) {
|
|
2
|
-
// Set CORS headers to allow cross-origin requests
|
|
3
|
-
res.setHeader('Access-Control-Allow-Origin', '*')
|
|
4
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
|
|
5
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
|
6
|
-
|
|
7
|
-
// Handle preflight requests
|
|
8
|
-
if (req.method === 'OPTIONS') {
|
|
9
|
-
res.status(200).end()
|
|
10
|
-
return
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
res.status(200).json({
|
|
14
|
-
metadata: 'example metadata',
|
|
15
|
-
})
|
|
16
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 2,
|
|
3
|
-
"builds": [
|
|
4
|
-
{
|
|
5
|
-
"src": "api/**/*.js",
|
|
6
|
-
"use": "@vercel/node"
|
|
7
|
-
},
|
|
8
|
-
{
|
|
9
|
-
"src": "public/**/*",
|
|
10
|
-
"use": "@vercel/static"
|
|
11
|
-
}
|
|
12
|
-
],
|
|
13
|
-
"routes": [
|
|
14
|
-
{
|
|
15
|
-
"src": "/api/(.*)",
|
|
16
|
-
"dest": "/api/$1.js"
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"src": "/(.*)",
|
|
20
|
-
"dest": "/public/$1"
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}
|