tezign-ai-appstore-sdk 0.1.4 → 0.2.0-beta.2
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/README.md +51 -119
- package/dist/cli/open-api.d.ts +3 -0
- package/dist/cli/open-api.d.ts.map +1 -0
- package/dist/cli/open-api.js +4 -0
- package/dist/cli/open-api.js.map +1 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/open-api/auto-provision.d.ts +23 -0
- package/dist/open-api/auto-provision.d.ts.map +1 -0
- package/dist/open-api/auto-provision.js +345 -0
- package/dist/open-api/auto-provision.js.map +1 -0
- package/dist/open-api/browser-key-store.d.ts +8 -0
- package/dist/open-api/browser-key-store.d.ts.map +1 -0
- package/dist/open-api/browser-key-store.js +25 -0
- package/dist/open-api/browser-key-store.js.map +1 -0
- package/dist/open-api/cli-key-store.d.ts +35 -0
- package/dist/open-api/cli-key-store.d.ts.map +1 -0
- package/dist/open-api/cli-key-store.js +281 -0
- package/dist/open-api/cli-key-store.js.map +1 -0
- package/dist/open-api/cli.d.ts +18 -0
- package/dist/open-api/cli.d.ts.map +1 -0
- package/dist/open-api/cli.js +1371 -0
- package/dist/open-api/cli.js.map +1 -0
- package/dist/open-api/client.d.ts +18 -0
- package/dist/open-api/client.d.ts.map +1 -0
- package/dist/open-api/client.js +171 -0
- package/dist/open-api/client.js.map +1 -0
- package/dist/open-api/project-local-config.d.ts +23 -0
- package/dist/open-api/project-local-config.d.ts.map +1 -0
- package/dist/open-api/project-local-config.js +114 -0
- package/dist/open-api/project-local-config.js.map +1 -0
- package/dist/open-api/runtime-key.d.ts +9 -0
- package/dist/open-api/runtime-key.d.ts.map +1 -0
- package/dist/open-api/runtime-key.js +72 -0
- package/dist/open-api/runtime-key.js.map +1 -0
- package/dist/open-api/source-archive.d.ts +47 -0
- package/dist/open-api/source-archive.d.ts.map +1 -0
- package/dist/open-api/source-archive.js +249 -0
- package/dist/open-api/source-archive.js.map +1 -0
- package/dist/open-api/types.d.ts +104 -0
- package/dist/open-api/types.d.ts.map +1 -0
- package/dist/open-api/types.js +2 -0
- package/dist/open-api/types.js.map +1 -0
- package/dist/storage/typed-storage.d.ts +0 -1
- package/dist/storage/typed-storage.d.ts.map +1 -1
- package/dist/storage/typed-storage.js +4 -7
- package/dist/storage/typed-storage.js.map +1 -1
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -1,152 +1,84 @@
|
|
|
1
1
|
# tezign-ai-appstore-sdk
|
|
2
2
|
|
|
3
|
-
AI 应用商店 SDK
|
|
3
|
+
AI 应用商店 SDK:提供开放接口、文件上传和结构化数据存储。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 文档索引
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
npm install tezign-ai-appstore-sdk
|
|
9
|
-
```
|
|
7
|
+
本包按能力拆分为多篇专文,关系如下:
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
- **Open API**
|
|
10
|
+
- [Open API / TS API](./docs/open-api-ts-api.md) — 第三方在代码中显式传 key 调用开放接口。
|
|
11
|
+
- [Open API CLI](./docs/open-api-cli.md) — 命令与程序化 CLI API 的完整参考(环境、绑定、自动打包、认证等)。
|
|
12
|
+
- [Open API CLI 使用 SOP](./docs/open-api-cli-sop.md) — 按场景的操作步骤,细节与参数以 CLI 专文为准。
|
|
13
|
+
- **其他能力**
|
|
14
|
+
- [OSS 上传](./docs/oss-upload.md)
|
|
15
|
+
- [Storage v2](./docs/storage-v2.md) — 客户端、Schema、类型化增删改查、错误与示例(**主技术文档**)。
|
|
16
|
+
- [SCHEMA.md](./docs/SCHEMA.md) — 在 Storage v2 之上侧重建模、校验、注册表与工程化实践,与上篇有分工。
|
|
17
|
+
- [STORAGE_V2_LLM_REFERENCE.md](./docs/STORAGE_V2_LLM_REFERENCE.md) — 给 LLM/Agent 的约定与易错点,与实现冲突时以代码为准。
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
专文细节不在此重复;下方「快速开始」仅提供最短可运行提示。
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
import { createOssUploadClient } from 'tezign-ai-appstore-sdk'
|
|
21
|
+
## 如何选择
|
|
17
22
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
})
|
|
23
|
+
- 接第三方应用或服务端直调开放接口 → [Open API / TS API](./docs/open-api-ts-api.md)
|
|
24
|
+
- 终端里授权与部署 → [SOP](./docs/open-api-cli-sop.md) + [Open API CLI](./docs/open-api-cli.md)
|
|
25
|
+
- 本地上传业务文件 → [OSS 上传](./docs/oss-upload.md)
|
|
26
|
+
- 结构化存储与 Schema → 先 [Storage v2](./docs/storage-v2.md),需要建模深度说明再读 [SCHEMA.md](./docs/SCHEMA.md)
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
file,
|
|
26
|
-
onProgress: (p) => console.log(`${p.loaded}/${p.total}`),
|
|
27
|
-
})
|
|
28
|
+
## 安装
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
```bash
|
|
31
|
+
npm install tezign-ai-appstore-sdk
|
|
30
32
|
```
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
## 快速开始
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
import { createSchemaClient, createSchema } from 'tezign-ai-appstore-sdk'
|
|
36
|
+
各能力有独立专文,避免在此重复展开;下面仅作最小可运行提示。
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
const postSchema = createSchema('posts')
|
|
39
|
-
.string('title', { required: true, filterable: true })
|
|
40
|
-
.string('content', { required: true })
|
|
41
|
-
.string('status', { enum: ['draft', 'published'], filterable: true })
|
|
42
|
-
.setVersion(1)
|
|
43
|
-
.build()
|
|
38
|
+
### Open API(TypeScript 客户端)
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
```ts
|
|
41
|
+
import { createOpenApiClient } from 'tezign-ai-appstore-sdk'
|
|
47
42
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
content: 'World',
|
|
52
|
-
status: 'published',
|
|
43
|
+
const client = createOpenApiClient({
|
|
44
|
+
baseUrl: 'https://platform.example.com',
|
|
45
|
+
apiKey: process.env.TEZIGN_OPEN_API_KEY,
|
|
53
46
|
})
|
|
54
47
|
```
|
|
55
48
|
|
|
56
|
-
|
|
49
|
+
密钥解析顺序、全部方法与错误类型见 [Open API / TS API](./docs/open-api-ts-api.md)。
|
|
57
50
|
|
|
58
|
-
|
|
51
|
+
### Open API CLI
|
|
59
52
|
|
|
60
|
-
|
|
61
|
-
2. **创建客户端** - 使用 `createSchemaClient` 自动完成初始化、迁移和客户端创建
|
|
62
|
-
3. **数据操作** - 通过返回的客户端进行类型安全的数据操作
|
|
53
|
+
终端用户推荐用 `tezign-ai-appstore` 管理环境、授权与项目。最常用命令与说明见 [Open API CLI](./docs/open-api-cli.md);分步操作见 [CLI 使用 SOP](./docs/open-api-cli-sop.md)。
|
|
63
54
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
.string('title', { required: true, filterable: true })
|
|
69
|
-
.string('content', { required: true })
|
|
70
|
-
.number('viewCount', { default: 0 })
|
|
71
|
-
.setVersion(1)
|
|
72
|
-
.setPolicy({
|
|
73
|
-
createSubjectsByScope: {
|
|
74
|
-
members: ['project:member'],
|
|
75
|
-
},
|
|
76
|
-
})
|
|
77
|
-
.build()
|
|
55
|
+
```bash
|
|
56
|
+
tezign-ai-appstore env add --env test --baseUrl https://test.example.com
|
|
57
|
+
tezign-ai-appstore auth login --env test
|
|
58
|
+
tezign-ai-appstore project init
|
|
78
59
|
```
|
|
79
60
|
|
|
80
|
-
|
|
61
|
+
### OSS 上传
|
|
81
62
|
|
|
82
|
-
|
|
83
|
-
- `required` - 是否必填
|
|
84
|
-
- `default` - 默认值
|
|
85
|
-
- `filterable` - 是否可过滤
|
|
86
|
-
- `sortable` - 是否可排序
|
|
87
|
-
- `previousName` - 声明之前的字段名(用于字段更名)
|
|
63
|
+
见 [OSS 上传](./docs/oss-upload.md)。
|
|
88
64
|
|
|
89
|
-
|
|
65
|
+
### Storage v2(结构化数据)
|
|
90
66
|
|
|
91
|
-
|
|
67
|
+
底层客户端、Schema、`createSchemaClient` 的完整 API 与类型见 [Storage v2](./docs/storage-v2.md)。数据建模、验证、多 Schema 管理见 [SCHEMA.md](./docs/SCHEMA.md)。面向 LLM/代码生成的补遗与边角行为见 [STORAGE_V2_LLM_REFERENCE.md](./docs/STORAGE_V2_LLM_REFERENCE.md)。
|
|
92
68
|
|
|
93
69
|
```ts
|
|
94
|
-
|
|
95
|
-
const postSchemaV2 = createSchema('posts')
|
|
96
|
-
.string('title', { required: true })
|
|
97
|
-
.string('authorId', {
|
|
98
|
-
filterable: true,
|
|
99
|
-
previousName: 'author' // 声明更名
|
|
100
|
-
})
|
|
101
|
-
.setVersion(2)
|
|
102
|
-
.build()
|
|
103
|
-
|
|
104
|
-
const db = createSchemaClient({ posts: postSchemaV2 }, storageClient)
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**预览变更**:
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
const db = createSchemaClient({ posts: postSchema }, storageClient, {
|
|
111
|
-
migrateOptions: {
|
|
112
|
-
dryRun: true,
|
|
113
|
-
onChangesDetected: (namespace, changes) => {
|
|
114
|
-
console.log(changes)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
})
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## 数据操作
|
|
121
|
-
|
|
122
|
-
```ts
|
|
123
|
-
// 创建
|
|
124
|
-
const post = await db.posts.create('post-1', { title: 'Hello' })
|
|
125
|
-
|
|
126
|
-
// 获取
|
|
127
|
-
const post = await db.posts.get('post-1')
|
|
70
|
+
import { createStorageClient, createSchema, createSchemaClient } from 'tezign-ai-appstore-sdk'
|
|
128
71
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
// 删除
|
|
133
|
-
await db.posts.delete('post-1')
|
|
134
|
-
|
|
135
|
-
// 查询
|
|
136
|
-
const result = await db.posts.findMany({
|
|
137
|
-
filter: { field: 'status', op: 'eq', value: 'published' },
|
|
138
|
-
sort: { field: '__sys.createdAt', direction: 'desc' },
|
|
139
|
-
limit: 20,
|
|
72
|
+
const storageClient = createStorageClient({
|
|
73
|
+
baseUrl: 'https://platform.example.com',
|
|
74
|
+
getAccessToken: async () => 'your-token',
|
|
140
75
|
})
|
|
141
76
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
## 完整文档
|
|
147
|
-
|
|
148
|
-
见 [API.md](./API.md)。
|
|
149
|
-
|
|
150
|
-
## License
|
|
77
|
+
const postSchema = createSchema('posts')
|
|
78
|
+
.string('title', { required: true })
|
|
79
|
+
.setVersion(1)
|
|
80
|
+
.build()
|
|
151
81
|
|
|
152
|
-
|
|
82
|
+
const db = createSchemaClient({ posts: postSchema }, storageClient)
|
|
83
|
+
await db.posts.create('post-1', { title: 'Hello' })
|
|
84
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-api.d.ts","sourceRoot":"","sources":["../../src/cli/open-api.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-api.js","sourceRoot":"","sources":["../../src/cli/open-api.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,MAAM,aAAa,EAAE,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { createStorageClient, StorageClient, StorageError } from './storage/storage.js';
|
|
2
2
|
export type { StorageItem, Filter, Sort, StorageIndexDefinition, NamespacePolicy, PermissionResource, PermissionAction, CheckPermissionRequest, CheckPermissionResponse, } from './storage/storage-types.js';
|
|
3
|
-
export { createSchema, SchemaBuilder, OWNER_ID, subject, buildAclConfig, } from './storage/schema.js';
|
|
3
|
+
export { createSchema, SchemaBuilder, SchemaRegistry, SchemaValidator, OWNER_ID, subject, buildAclConfig, } from './storage/schema.js';
|
|
4
4
|
export type { FieldDef, FieldPermission, StringFieldDef, NumberFieldDef, BooleanFieldDef, DateTimeFieldDef, JsonFieldDef, FieldsDefinition, SchemaDefinition, IndexConfig, AccessConfig, InferSchemaType, CreateSchemaType, UpdateSchemaType, SchemaAclConfig, AclConfig, } from './storage/schema.js';
|
|
5
5
|
export type { TypedStorageClient } from './storage/typed-storage.js';
|
|
6
6
|
export { createTypedStorage } from './storage/typed-storage.js';
|
|
@@ -10,4 +10,14 @@ export { createSchemaClient, defineSchemas, PermissionError, UserCancelledError,
|
|
|
10
10
|
export type { SchemaDefinitions, InferSchemaTypes, CreateSchemaClientOptions, MigrateOptions, MigrationChange, MigrationResult, ConfirmDialogOptions, ConfirmDialogResult, ConfirmDialogFunction, } from './storage/schema-client.js';
|
|
11
11
|
export { createOssUploadClient } from './uploader/index.js';
|
|
12
12
|
export type { CreateOssUploadClientOptions, CompleteUploadResult, UploadListItem, UploadListResult, } from './uploader/index.js';
|
|
13
|
+
export { createOpenApiClient, OpenApiError } from './open-api/client.js';
|
|
14
|
+
export { createBrowserOpenApiKeyStore, DEFAULT_OPEN_API_STORAGE_KEY, } from './open-api/browser-key-store.js';
|
|
15
|
+
export type { CreateBrowserOpenApiKeyStoreOptions } from './open-api/browser-key-store.js';
|
|
16
|
+
export type { BrowserOpenApiKeyStore } from './open-api/types.js';
|
|
17
|
+
export { DEFAULT_OPEN_API_ENV_KEY, readOpenApiRuntimeKey, writeOpenApiRuntimeKey, } from './open-api/runtime-key.js';
|
|
18
|
+
export type { OpenApiRuntimeKeyOptions } from './open-api/runtime-key.js';
|
|
19
|
+
export { createOpenApiCliClient, ensureOpenApiCliKey, runOpenApiCli, } from './open-api/cli.js';
|
|
20
|
+
export type { OpenApiCliOptions, OpenApiCliIO } from './open-api/cli.js';
|
|
21
|
+
export type { OpenApiCliAutoProvisionOptions } from './open-api/auto-provision.js';
|
|
22
|
+
export type { CreateOpenApiClientOptions, CreateOpenApiProjectInput, UpdateOpenApiProjectInput, DeployOpenApiProjectInput, UploadOpenApiProjectSourceInput, OpenApiAppType, OpenApiProject, OpenApiDeployment, OpenApiProjectSourcePackage, OpenApiErrorPayload, OpenApiResponseEnvelope, OpenApiResponseMeta, } from './open-api/types.js';
|
|
13
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACvF,YAAY,EACV,WAAW,EACX,MAAM,EACN,IAAI,EACJ,sBAAsB,EACtB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,OAAO,EACP,cAAc,GACf,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,QAAQ,EACR,eAAe,EACf,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,SAAS,GACV,MAAM,qBAAqB,CAAA;AAE5B,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAE/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAA;AAC5E,YAAY,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AAEjG,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,YAAY,GACb,MAAM,4BAA4B,CAAA;AACnC,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,YAAY,EACV,4BAA4B,EAC5B,oBAAoB,EACpB,cAAc,EACd,gBAAgB,GACjB,MAAM,qBAAqB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACvF,YAAY,EACV,WAAW,EACX,MAAM,EACN,IAAI,EACJ,sBAAsB,EACtB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,eAAe,EACf,QAAQ,EACR,OAAO,EACP,cAAc,GACf,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,QAAQ,EACR,eAAe,EACf,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,SAAS,GACV,MAAM,qBAAqB,CAAA;AAE5B,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAE/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAA;AAC5E,YAAY,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AAEjG,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,YAAY,GACb,MAAM,4BAA4B,CAAA;AACnC,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,YAAY,EACV,4BAA4B,EAC5B,oBAAoB,EACpB,cAAc,EACd,gBAAgB,GACjB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,iCAAiC,CAAA;AACxC,YAAY,EAAE,mCAAmC,EAAE,MAAM,iCAAiC,CAAA;AAC1F,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACzE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,GACd,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACxE,YAAY,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAA;AAClF,YAAY,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,+BAA+B,EAC/B,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,2BAA2B,EAC3B,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,qBAAqB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export { createStorageClient, StorageClient, StorageError } from './storage/storage.js';
|
|
2
|
-
export { createSchema, SchemaBuilder, OWNER_ID, subject, buildAclConfig, } from './storage/schema.js';
|
|
2
|
+
export { createSchema, SchemaBuilder, SchemaRegistry, SchemaValidator, OWNER_ID, subject, buildAclConfig, } from './storage/schema.js';
|
|
3
3
|
export { createTypedStorage } from './storage/typed-storage.js';
|
|
4
4
|
export { createFieldPermissionChecker } from './storage/field-permission.js';
|
|
5
5
|
export { createSchemaClient, defineSchemas, PermissionError, UserCancelledError, SchemaClient, } from './storage/schema-client.js';
|
|
6
6
|
export { createOssUploadClient } from './uploader/index.js';
|
|
7
|
+
export { createOpenApiClient, OpenApiError } from './open-api/client.js';
|
|
8
|
+
export { createBrowserOpenApiKeyStore, DEFAULT_OPEN_API_STORAGE_KEY, } from './open-api/browser-key-store.js';
|
|
9
|
+
export { DEFAULT_OPEN_API_ENV_KEY, readOpenApiRuntimeKey, writeOpenApiRuntimeKey, } from './open-api/runtime-key.js';
|
|
10
|
+
export { createOpenApiCliClient, ensureOpenApiCliKey, runOpenApiCli, } from './open-api/cli.js';
|
|
7
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAavF,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,OAAO,EACP,cAAc,GACf,MAAM,qBAAqB,CAAA;AAqB5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAE/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAA;AAG5E,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,YAAY,GACb,MAAM,4BAA4B,CAAA;AAanC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAavF,OAAO,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,eAAe,EACf,QAAQ,EACR,OAAO,EACP,cAAc,GACf,MAAM,qBAAqB,CAAA;AAqB5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAE/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAA;AAG5E,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,YAAY,GACb,MAAM,4BAA4B,CAAA;AAanC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAQ3D,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,iCAAiC,CAAA;AAGxC,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,GACd,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const OPEN_API_PROVISION_MESSAGE_TYPE = "tezign:open-api-key:provisioned";
|
|
2
|
+
export interface OpenApiCliAutoProvisionOptions {
|
|
3
|
+
enabled?: boolean;
|
|
4
|
+
openApiPagePath?: string;
|
|
5
|
+
requestTimeoutMs?: number;
|
|
6
|
+
keyName?: string;
|
|
7
|
+
scopes?: string[];
|
|
8
|
+
openUrl?: (url: string) => void | Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
interface EnsureAutoProvisionedOpenApiKeyOptions {
|
|
11
|
+
baseUrl: string;
|
|
12
|
+
envKey?: string;
|
|
13
|
+
storageKey?: string;
|
|
14
|
+
autoProvision?: boolean | OpenApiCliAutoProvisionOptions;
|
|
15
|
+
}
|
|
16
|
+
interface CliOpenCommandConfig {
|
|
17
|
+
command: string;
|
|
18
|
+
args: string[];
|
|
19
|
+
}
|
|
20
|
+
export declare function getCliProvisionOpenCommandConfig(platform: string, url: string): CliOpenCommandConfig;
|
|
21
|
+
export declare function ensureAutoProvisionedOpenApiKey(options: EnsureAutoProvisionedOpenApiKeyOptions): Promise<string | null>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=auto-provision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-provision.d.ts","sourceRoot":"","sources":["../../src/open-api/auto-provision.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,+BAA+B,oCAAoC,CAAA;AAehF,MAAM,WAAW,8BAA8B;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAChD;AAED,UAAU,sCAAsC;IAC9C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,OAAO,GAAG,8BAA8B,CAAA;CACzD;AA0BD,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAsUD,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,GACV,oBAAoB,CAatB;AAmDD,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,sCAAsC,GAC9C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgCxB"}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { DEFAULT_OPEN_API_STORAGE_KEY } from './browser-key-store.js';
|
|
2
|
+
import { DEFAULT_OPEN_API_ENV_KEY, readOpenApiRuntimeKey, writeOpenApiRuntimeKey } from './runtime-key.js';
|
|
3
|
+
export const OPEN_API_PROVISION_MESSAGE_TYPE = 'tezign:open-api-key:provisioned';
|
|
4
|
+
const DEFAULT_OPEN_API_PAGE_PATH = '/apps/open-api';
|
|
5
|
+
const DEFAULT_OPEN_API_SCOPES = [
|
|
6
|
+
'project:read',
|
|
7
|
+
'project:create',
|
|
8
|
+
'project:update',
|
|
9
|
+
'project:deploy',
|
|
10
|
+
'deployment:read',
|
|
11
|
+
];
|
|
12
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 120000;
|
|
13
|
+
const CLI_CALLBACK_PATH = '/__tezign_open_api_callback__';
|
|
14
|
+
let pendingProvisionPromise = null;
|
|
15
|
+
function isBrowserEnvironment() {
|
|
16
|
+
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
17
|
+
}
|
|
18
|
+
function isNodeEnvironment() {
|
|
19
|
+
return typeof process !== 'undefined' && Boolean(process.versions?.node);
|
|
20
|
+
}
|
|
21
|
+
function importNodeModule(specifier) {
|
|
22
|
+
return import(/* @vite-ignore */ specifier);
|
|
23
|
+
}
|
|
24
|
+
function createRequestId() {
|
|
25
|
+
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
|
26
|
+
return crypto.randomUUID();
|
|
27
|
+
}
|
|
28
|
+
return `open-api-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
29
|
+
}
|
|
30
|
+
function buildDefaultKeyName() {
|
|
31
|
+
if (typeof window !== 'undefined') {
|
|
32
|
+
return `AI AppStore SDK / ${window.location.host}`.slice(0, 60);
|
|
33
|
+
}
|
|
34
|
+
const scriptName = typeof process !== 'undefined'
|
|
35
|
+
? process.argv?.[1]?.split(/[\\/]/).pop() || process.title || 'cli'
|
|
36
|
+
: 'cli';
|
|
37
|
+
return `AI AppStore SDK / ${scriptName}`.slice(0, 60);
|
|
38
|
+
}
|
|
39
|
+
function normalizeAutoProvisionOptions(baseUrl, options) {
|
|
40
|
+
const rawOptions = typeof options === 'object' && options !== null
|
|
41
|
+
? options
|
|
42
|
+
: {};
|
|
43
|
+
const enabled = options !== false && rawOptions.enabled !== false;
|
|
44
|
+
const appOrigin = typeof window !== 'undefined' ? window.location.origin : baseUrl;
|
|
45
|
+
const pageUrl = new URL(rawOptions.openApiPagePath || DEFAULT_OPEN_API_PAGE_PATH, baseUrl || appOrigin);
|
|
46
|
+
const keyName = (rawOptions.keyName || buildDefaultKeyName()).trim() || buildDefaultKeyName();
|
|
47
|
+
const scopes = Array.isArray(rawOptions.scopes)
|
|
48
|
+
? Array.from(new Set(rawOptions.scopes
|
|
49
|
+
.filter((scope) => typeof scope === 'string')
|
|
50
|
+
.map((scope) => scope.trim())
|
|
51
|
+
.filter(Boolean)))
|
|
52
|
+
: [];
|
|
53
|
+
return {
|
|
54
|
+
enabled,
|
|
55
|
+
pageUrl,
|
|
56
|
+
requestTimeoutMs: typeof rawOptions.requestTimeoutMs === 'number' && rawOptions.requestTimeoutMs > 0
|
|
57
|
+
? rawOptions.requestTimeoutMs
|
|
58
|
+
: DEFAULT_REQUEST_TIMEOUT_MS,
|
|
59
|
+
keyName: keyName.slice(0, 60),
|
|
60
|
+
scopes: scopes.length > 0 ? scopes : DEFAULT_OPEN_API_SCOPES,
|
|
61
|
+
targetOrigin: appOrigin,
|
|
62
|
+
openUrl: rawOptions.openUrl,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function buildProvisionPageUrl(config, requestId, extraParams) {
|
|
66
|
+
const pageUrl = new URL(config.pageUrl.toString());
|
|
67
|
+
pageUrl.searchParams.set('sdkAutoCreate', '1');
|
|
68
|
+
pageUrl.searchParams.set('sdkRequestId', requestId);
|
|
69
|
+
pageUrl.searchParams.set('sdkScopes', config.scopes.join(','));
|
|
70
|
+
pageUrl.searchParams.set('sdkKeyName', config.keyName);
|
|
71
|
+
for (const [key, value] of Object.entries(extraParams)) {
|
|
72
|
+
pageUrl.searchParams.set(key, value);
|
|
73
|
+
}
|
|
74
|
+
return pageUrl;
|
|
75
|
+
}
|
|
76
|
+
async function ensureBrowserOpenApiKey(options, config) {
|
|
77
|
+
const envKey = options.envKey || DEFAULT_OPEN_API_ENV_KEY;
|
|
78
|
+
const storageKey = options.storageKey || DEFAULT_OPEN_API_STORAGE_KEY;
|
|
79
|
+
if (!document.body) {
|
|
80
|
+
throw new Error('Document body is not ready for Open API auto provisioning');
|
|
81
|
+
}
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const requestId = createRequestId();
|
|
84
|
+
const iframe = document.createElement('iframe');
|
|
85
|
+
const frameUrl = buildProvisionPageUrl(config, requestId, {
|
|
86
|
+
sdkTargetOrigin: config.targetOrigin,
|
|
87
|
+
});
|
|
88
|
+
const timeoutId = window.setTimeout(() => {
|
|
89
|
+
cleanup();
|
|
90
|
+
reject(new Error('Open API Key 自动创建超时,请稍后重试'));
|
|
91
|
+
}, config.requestTimeoutMs);
|
|
92
|
+
const cleanup = () => {
|
|
93
|
+
window.clearTimeout(timeoutId);
|
|
94
|
+
window.removeEventListener('message', handleMessage);
|
|
95
|
+
iframe.removeEventListener('error', handleError);
|
|
96
|
+
iframe.remove();
|
|
97
|
+
};
|
|
98
|
+
const handleError = () => {
|
|
99
|
+
cleanup();
|
|
100
|
+
reject(new Error('Open API 授权页加载失败'));
|
|
101
|
+
};
|
|
102
|
+
const handleMessage = (event) => {
|
|
103
|
+
if (event.origin !== config.pageUrl.origin)
|
|
104
|
+
return;
|
|
105
|
+
if (event.source !== iframe.contentWindow)
|
|
106
|
+
return;
|
|
107
|
+
const payload = event.data;
|
|
108
|
+
if (!payload || payload.type !== OPEN_API_PROVISION_MESSAGE_TYPE)
|
|
109
|
+
return;
|
|
110
|
+
if (payload.requestId !== requestId)
|
|
111
|
+
return;
|
|
112
|
+
cleanup();
|
|
113
|
+
if (!payload.success || typeof payload.apiKey !== 'string') {
|
|
114
|
+
reject(new Error(payload.error || 'Open API Key 自动创建失败'));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const apiKey = writeOpenApiRuntimeKey(payload.apiKey, { envKey, storageKey });
|
|
118
|
+
resolve(apiKey);
|
|
119
|
+
};
|
|
120
|
+
window.addEventListener('message', handleMessage);
|
|
121
|
+
iframe.addEventListener('error', handleError);
|
|
122
|
+
iframe.style.display = 'none';
|
|
123
|
+
iframe.setAttribute('aria-hidden', 'true');
|
|
124
|
+
iframe.setAttribute('tabindex', '-1');
|
|
125
|
+
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');
|
|
126
|
+
iframe.src = frameUrl.toString();
|
|
127
|
+
document.body.appendChild(iframe);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
async function readUrlEncodedBody(request) {
|
|
131
|
+
let body = '';
|
|
132
|
+
const textDecoder = new TextDecoder();
|
|
133
|
+
for await (const chunk of request) {
|
|
134
|
+
body += typeof chunk === 'string' ? chunk : textDecoder.decode(chunk, { stream: true });
|
|
135
|
+
}
|
|
136
|
+
body += textDecoder.decode();
|
|
137
|
+
return new URLSearchParams(body);
|
|
138
|
+
}
|
|
139
|
+
function renderCliCallbackHtml(title, message) {
|
|
140
|
+
return `<!doctype html>
|
|
141
|
+
<html lang="zh-CN">
|
|
142
|
+
<head>
|
|
143
|
+
<meta charset="utf-8" />
|
|
144
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
145
|
+
<title>${title}</title>
|
|
146
|
+
<style>
|
|
147
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; margin: 0; background: #f8fafc; color: #0f172a; }
|
|
148
|
+
main { max-width: 560px; margin: 64px auto; padding: 32px; background: white; border-radius: 24px; box-shadow: 0 20px 60px rgba(15, 23, 42, 0.08); }
|
|
149
|
+
h1 { margin: 0 0 12px; font-size: 24px; }
|
|
150
|
+
p { margin: 0; line-height: 1.7; color: #475569; }
|
|
151
|
+
</style>
|
|
152
|
+
</head>
|
|
153
|
+
<body>
|
|
154
|
+
<main>
|
|
155
|
+
<h1>${title}</h1>
|
|
156
|
+
<p>${message}</p>
|
|
157
|
+
</main>
|
|
158
|
+
<script>window.close()</script>
|
|
159
|
+
</body>
|
|
160
|
+
</html>`;
|
|
161
|
+
}
|
|
162
|
+
function respondWithHtml(response, statusCode, title, message) {
|
|
163
|
+
response.statusCode = statusCode;
|
|
164
|
+
response.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
165
|
+
response.end(renderCliCallbackHtml(title, message));
|
|
166
|
+
}
|
|
167
|
+
async function createCliProvisionBridge(requestId, requestTimeoutMs) {
|
|
168
|
+
const { createServer } = await importNodeModule('node:http');
|
|
169
|
+
const state = createRequestId();
|
|
170
|
+
let server = null;
|
|
171
|
+
let isSettled = false;
|
|
172
|
+
let timeoutId = null;
|
|
173
|
+
let resolveResult;
|
|
174
|
+
let rejectResult;
|
|
175
|
+
const result = new Promise((resolve, reject) => {
|
|
176
|
+
resolveResult = resolve;
|
|
177
|
+
rejectResult = reject;
|
|
178
|
+
});
|
|
179
|
+
const dispose = () => {
|
|
180
|
+
if (timeoutId) {
|
|
181
|
+
clearTimeout(timeoutId);
|
|
182
|
+
timeoutId = null;
|
|
183
|
+
}
|
|
184
|
+
if (server) {
|
|
185
|
+
server.close();
|
|
186
|
+
server = null;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
const settle = (resolver) => {
|
|
190
|
+
if (isSettled)
|
|
191
|
+
return;
|
|
192
|
+
isSettled = true;
|
|
193
|
+
dispose();
|
|
194
|
+
resolver();
|
|
195
|
+
};
|
|
196
|
+
server = createServer(async (request, response) => {
|
|
197
|
+
const requestUrl = new URL(request.url || '/', 'http://127.0.0.1');
|
|
198
|
+
if (requestUrl.pathname !== CLI_CALLBACK_PATH) {
|
|
199
|
+
response.statusCode = 404;
|
|
200
|
+
response.end('Not Found');
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (requestUrl.searchParams.get('state') !== state) {
|
|
204
|
+
respondWithHtml(response, 400, '请求无效', '回调状态校验失败,请重新发起 Open API 授权。');
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
let payload;
|
|
208
|
+
if (request.method === 'POST') {
|
|
209
|
+
payload = await readUrlEncodedBody(request);
|
|
210
|
+
}
|
|
211
|
+
else if (request.method === 'GET') {
|
|
212
|
+
payload = requestUrl.searchParams;
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
response.statusCode = 405;
|
|
216
|
+
response.end('Method Not Allowed');
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (payload.get('requestId') !== requestId) {
|
|
220
|
+
respondWithHtml(response, 400, '请求无效', '授权请求标识不匹配,请重新发起 Open API 授权。');
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const status = payload.get('status');
|
|
224
|
+
if (status === 'success') {
|
|
225
|
+
const apiKey = payload.get('apiKey')?.trim();
|
|
226
|
+
if (!apiKey) {
|
|
227
|
+
respondWithHtml(response, 400, '回传失败', '页面没有返回可用的 Open API Key。');
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
response.statusCode = 200;
|
|
231
|
+
response.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
232
|
+
response.end(renderCliCallbackHtml('授权完成', 'Open API Key 已回传给 CLI,当前终端会继续执行原始命令。你现在可以关闭这个页面。'), () => {
|
|
233
|
+
settle(() => resolveResult(apiKey));
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const errorMessage = payload.get('error')?.trim() || 'Open API Key 自动创建失败';
|
|
238
|
+
response.statusCode = 200;
|
|
239
|
+
response.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
240
|
+
response.end(renderCliCallbackHtml('授权失败', errorMessage), () => {
|
|
241
|
+
settle(() => rejectResult(new Error(errorMessage)));
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
await new Promise((resolve, reject) => {
|
|
245
|
+
server.once('error', reject);
|
|
246
|
+
server.listen(0, '127.0.0.1', () => resolve());
|
|
247
|
+
});
|
|
248
|
+
const address = server.address();
|
|
249
|
+
const port = typeof address === 'object' && address ? address.port : null;
|
|
250
|
+
if (!port) {
|
|
251
|
+
dispose();
|
|
252
|
+
throw new Error('无法为 Open API CLI 授权分配本地回调端口');
|
|
253
|
+
}
|
|
254
|
+
timeoutId = setTimeout(() => {
|
|
255
|
+
settle(() => rejectResult(new Error('Open API Key 自动创建超时,请稍后重试')));
|
|
256
|
+
}, requestTimeoutMs);
|
|
257
|
+
const callbackUrl = new URL(CLI_CALLBACK_PATH, `http://127.0.0.1:${String(port)}`);
|
|
258
|
+
callbackUrl.searchParams.set('state', state);
|
|
259
|
+
return {
|
|
260
|
+
callbackUrl: callbackUrl.toString(),
|
|
261
|
+
dispose,
|
|
262
|
+
result,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
export function getCliProvisionOpenCommandConfig(platform, url) {
|
|
266
|
+
if (platform === 'win32') {
|
|
267
|
+
return {
|
|
268
|
+
command: 'rundll32.exe',
|
|
269
|
+
args: ['url.dll,FileProtocolHandler', url],
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
if (platform === 'darwin') {
|
|
273
|
+
return { command: 'open', args: [url] };
|
|
274
|
+
}
|
|
275
|
+
return { command: 'xdg-open', args: [url] };
|
|
276
|
+
}
|
|
277
|
+
async function openCliProvisionUrl(url, openUrl) {
|
|
278
|
+
if (openUrl) {
|
|
279
|
+
await openUrl(url);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const { spawn } = await importNodeModule('node:child_process');
|
|
283
|
+
const platform = typeof process !== 'undefined' ? process.platform : 'unknown';
|
|
284
|
+
const commandConfig = getCliProvisionOpenCommandConfig(platform, url);
|
|
285
|
+
await new Promise((resolve, reject) => {
|
|
286
|
+
const child = spawn(commandConfig.command, commandConfig.args, {
|
|
287
|
+
detached: true,
|
|
288
|
+
stdio: 'ignore',
|
|
289
|
+
});
|
|
290
|
+
child.once('error', reject);
|
|
291
|
+
child.once('spawn', () => {
|
|
292
|
+
child.unref();
|
|
293
|
+
resolve();
|
|
294
|
+
});
|
|
295
|
+
}).catch((error) => {
|
|
296
|
+
const message = error instanceof Error ? error.message : 'unknown error';
|
|
297
|
+
throw new Error(`无法自动打开浏览器,请手动访问此链接完成 Open API 授权:${url}(${message})`);
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
async function ensureCliOpenApiKey(config) {
|
|
301
|
+
const requestId = createRequestId();
|
|
302
|
+
const bridge = await createCliProvisionBridge(requestId, config.requestTimeoutMs);
|
|
303
|
+
const pageUrl = buildProvisionPageUrl(config, requestId, {
|
|
304
|
+
sdkMode: 'cli',
|
|
305
|
+
sdkCallback: bridge.callbackUrl,
|
|
306
|
+
});
|
|
307
|
+
try {
|
|
308
|
+
await openCliProvisionUrl(pageUrl.toString(), config.openUrl);
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
bridge.dispose();
|
|
312
|
+
throw error;
|
|
313
|
+
}
|
|
314
|
+
const apiKey = await bridge.result;
|
|
315
|
+
return apiKey;
|
|
316
|
+
}
|
|
317
|
+
export async function ensureAutoProvisionedOpenApiKey(options) {
|
|
318
|
+
const storageKey = options.storageKey || DEFAULT_OPEN_API_STORAGE_KEY;
|
|
319
|
+
if (isBrowserEnvironment()) {
|
|
320
|
+
const envKey = options.envKey || DEFAULT_OPEN_API_ENV_KEY;
|
|
321
|
+
const existingKey = readOpenApiRuntimeKey({ envKey, storageKey });
|
|
322
|
+
if (existingKey)
|
|
323
|
+
return existingKey;
|
|
324
|
+
}
|
|
325
|
+
const config = normalizeAutoProvisionOptions(options.baseUrl, options.autoProvision);
|
|
326
|
+
if (!config.enabled)
|
|
327
|
+
return null;
|
|
328
|
+
if (pendingProvisionPromise) {
|
|
329
|
+
return pendingProvisionPromise;
|
|
330
|
+
}
|
|
331
|
+
if (isBrowserEnvironment()) {
|
|
332
|
+
pendingProvisionPromise = ensureBrowserOpenApiKey(options, config).finally(() => {
|
|
333
|
+
pendingProvisionPromise = null;
|
|
334
|
+
});
|
|
335
|
+
return pendingProvisionPromise;
|
|
336
|
+
}
|
|
337
|
+
if (isNodeEnvironment()) {
|
|
338
|
+
pendingProvisionPromise = ensureCliOpenApiKey(config).finally(() => {
|
|
339
|
+
pendingProvisionPromise = null;
|
|
340
|
+
});
|
|
341
|
+
return pendingProvisionPromise;
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=auto-provision.js.map
|