@tbox.cn/app-provider-custom 0.1.0
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/AGENTS.md +33 -0
- package/LICENSE +21 -0
- package/README.md +8 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +5 -0
- package/dist/server/index.d.ts +40 -0
- package/dist/server/index.js +15 -0
- package/package.json +49 -0
- package/src/index.ts +5 -0
- package/src/server/index.ts +40 -0
- package/tbox.module.json +29 -0
- package/tests/provider-custom.test.ts +17 -0
- package/tsconfig.json +7 -0
- package/tsup.config.ts +18 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# provider-custom —— 自定义 API 实施落点(AI 集成指引)
|
|
2
|
+
|
|
3
|
+
本包是**自定义厂商(自定义 API)的 adapter 代码落点**:用户在 AI 构建面板为某服务保存
|
|
4
|
+
「自定义 API」配置(内联声明)后,运行时因供给不在场报 `PROVIDER_NOT_IMPLEMENTED`——
|
|
5
|
+
由 AI 助手按本指引在本包实施 adapter,注册命中后配置即刻转 ok。
|
|
6
|
+
|
|
7
|
+
## 实施三步
|
|
8
|
+
|
|
9
|
+
1. **读声明**:`config/integrations.json` 中目标服务(如 `parking.query`)的
|
|
10
|
+
`provider` 为对象(内联声明:`{ provider, credentialType, configSchema? }`)+
|
|
11
|
+
`implementation` 字面量——这就是要实现的厂商身份与凭据约定。
|
|
12
|
+
2. **实现 adapter**:在 `src/server/` 新建实现文件,实现该服务对应模块的 Port 接口
|
|
13
|
+
(接口定义见对应业务模块 `src/server/ports/`;连接参数 = 绑定组 `config`,实例键 =
|
|
14
|
+
`input.instanceId`)。adapter 工厂签名:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
const factory: ServiceAdapterFactory = (input) => new MyApiServiceImpl(input);
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
3. **注册**:在 `src/server/index.ts` 的 `register(ctx)` 中调用
|
|
21
|
+
`ctx.integrations?.registerAdapter('<provider 名>', '<implementation>', factory)`。
|
|
22
|
+
多个自定义 API 均注册到本包(单包多厂商,注册表双键不关心包边界)。
|
|
23
|
+
|
|
24
|
+
## 完成判据
|
|
25
|
+
|
|
26
|
+
- 应用重启后 `PROVIDER_NOT_IMPLEMENTED` 消失(register 命中);
|
|
27
|
+
- AI 构建面板该服务 chip 由「AI 实施中」转为厂商名、issues 清零。
|
|
28
|
+
|
|
29
|
+
## 真实厂商接入
|
|
30
|
+
|
|
31
|
+
对外提供正式 API 的厂商(支付/会员等大规模集成)走官方 provider 包形态:
|
|
32
|
+
manifest `contributes.providers.slots` 声明供给 + 独立包发布——参照
|
|
33
|
+
`modules/provider-mock`(结构样例)与 docs/reference/providers.md。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tbox.cn
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# @tbox.cn/app-provider-custom
|
|
2
|
+
|
|
3
|
+
自定义厂商实施落点空包(与 provider-mock 并列的中立空壳):manifest contributes 全空(零贡献
|
|
4
|
+
合法——descriptor zod 全 default),出厂无任何供给/需求/卡片声明,纯为 AI 实施自定义 API
|
|
5
|
+
adapter 提供**有形代码落点**。闭环机制见 AGENTS.md(SDK 零改动——registerAdapter 命中即转 ok)。
|
|
6
|
+
|
|
7
|
+
单包多厂商:多个自定义 API 的 adapter 均在此包注册。依赖精确裁剪 = app-sdk + app-contracts
|
|
8
|
+
(不消费领域 Port 类型,无 contracts-mall);无 client 入口;无 peerDependencies。
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ServerContext } from '@tbox.cn/app-sdk/server';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 自定义厂商实施落点空包·服务端入口(ai-build D10;单包多厂商——多个自定义 API 的
|
|
5
|
+
* adapter 均在此包 register,注册表双键不关心包边界)。
|
|
6
|
+
*
|
|
7
|
+
* 零贡献合法(manifest contributes 全空——descriptor zod 全 default):本包出厂无任何
|
|
8
|
+
* 供给/需求/卡片声明,纯为 AI 实施提供**有形代码落点**。运行时闭环(SDK 零改动):
|
|
9
|
+
* 1. 用户在面板为某服务保存内联声明(自定义 API:provider 对象 + implementation 字面量);
|
|
10
|
+
* 2. 应用启动解析该绑定 → 供给不在场 → PROVIDER_NOT_IMPLEMENTED(fail-visible);
|
|
11
|
+
* 3. AI 按 AGENTS.md 指引在本包实现 adapter(下 factory 工厂签名)并在 register 挂载
|
|
12
|
+
* registerAdapter(provider, implementation, factory);
|
|
13
|
+
* 4. 重启后 register 命中 → 内联声明即刻转 ok——转变即完成信号(面板 issues 清零)。
|
|
14
|
+
*
|
|
15
|
+
* 真实厂商接入(官方 provider 包形态:manifest 槽声明 + 独立包发布)跳转见 AGENTS.md。
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
declare const PROVIDER_CUSTOM = "provider-custom";
|
|
19
|
+
/**
|
|
20
|
+
* adapter 工厂签名示例(真实实施时替换本注释为具体 adapter 注册):
|
|
21
|
+
*
|
|
22
|
+
* const myApiAdapterFactory: ServiceAdapterFactory = (input) => {
|
|
23
|
+
* // input.service 服务 id(如 'parking.query')
|
|
24
|
+
* // input.instanceId 部署实例键(mall 场景 = mallId;通配激活时由框架解析)
|
|
25
|
+
* // input.config 绑定组五层合并后的连接参数(面板保存的 baseUrl 等)
|
|
26
|
+
* // 返回:实现该服务 Port 的 adapter 实例(模块 src/server/ports 定义)
|
|
27
|
+
* return new MyApiServiceImpl(input);
|
|
28
|
+
* };
|
|
29
|
+
* ctx.integrations?.registerAdapter('my-custom-api', 'my-custom-parking@1', myApiAdapterFactory);
|
|
30
|
+
*/
|
|
31
|
+
declare function register(ctx: ServerContext): void;
|
|
32
|
+
declare const serverModule: {
|
|
33
|
+
declaration: {
|
|
34
|
+
moduleId: string;
|
|
35
|
+
};
|
|
36
|
+
cards: {};
|
|
37
|
+
register: typeof register;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { PROVIDER_CUSTOM, register, serverModule };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// src/server/index.ts
|
|
2
|
+
var PROVIDER_CUSTOM = "provider-custom";
|
|
3
|
+
function register(ctx) {
|
|
4
|
+
void ctx;
|
|
5
|
+
}
|
|
6
|
+
var serverModule = {
|
|
7
|
+
declaration: { moduleId: "provider-custom" },
|
|
8
|
+
cards: {},
|
|
9
|
+
register
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
PROVIDER_CUSTOM,
|
|
13
|
+
register,
|
|
14
|
+
serverModule
|
|
15
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tbox.cn/app-provider-custom",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "自定义厂商实施落点空包(中立空壳):内联声明(自定义 API)的 adapter 代码落点——AI 按 AGENTS.md 指引实施,registerAdapter 命中即转 ok。单包多厂商。",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"./server": {
|
|
12
|
+
"types": "./dist/server/index.d.ts",
|
|
13
|
+
"import": "./dist/server/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@tbox.cn/app-sdk": "0.17.0",
|
|
18
|
+
"@tbox.cn/app-contracts": "0.9.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "24.13.3",
|
|
22
|
+
"typescript": "5.9.3",
|
|
23
|
+
"vitest": "4.1.10",
|
|
24
|
+
"tsup": "8.5.1"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"src",
|
|
29
|
+
"tests",
|
|
30
|
+
"tbox.module.json",
|
|
31
|
+
"tsconfig.json",
|
|
32
|
+
"tsup.config.ts",
|
|
33
|
+
"AGENTS.md",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=20.0.0"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"scripts": {
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"build": "tsup"
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 自定义厂商实施落点空包·服务端入口(ai-build D10;单包多厂商——多个自定义 API 的
|
|
3
|
+
* adapter 均在此包 register,注册表双键不关心包边界)。
|
|
4
|
+
*
|
|
5
|
+
* 零贡献合法(manifest contributes 全空——descriptor zod 全 default):本包出厂无任何
|
|
6
|
+
* 供给/需求/卡片声明,纯为 AI 实施提供**有形代码落点**。运行时闭环(SDK 零改动):
|
|
7
|
+
* 1. 用户在面板为某服务保存内联声明(自定义 API:provider 对象 + implementation 字面量);
|
|
8
|
+
* 2. 应用启动解析该绑定 → 供给不在场 → PROVIDER_NOT_IMPLEMENTED(fail-visible);
|
|
9
|
+
* 3. AI 按 AGENTS.md 指引在本包实现 adapter(下 factory 工厂签名)并在 register 挂载
|
|
10
|
+
* registerAdapter(provider, implementation, factory);
|
|
11
|
+
* 4. 重启后 register 命中 → 内联声明即刻转 ok——转变即完成信号(面板 issues 清零)。
|
|
12
|
+
*
|
|
13
|
+
* 真实厂商接入(官方 provider 包形态:manifest 槽声明 + 独立包发布)跳转见 AGENTS.md。
|
|
14
|
+
*/
|
|
15
|
+
import type { ServerContext, ServerModule } from '@tbox.cn/app-sdk/server';
|
|
16
|
+
|
|
17
|
+
export const PROVIDER_CUSTOM = 'provider-custom';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* adapter 工厂签名示例(真实实施时替换本注释为具体 adapter 注册):
|
|
21
|
+
*
|
|
22
|
+
* const myApiAdapterFactory: ServiceAdapterFactory = (input) => {
|
|
23
|
+
* // input.service 服务 id(如 'parking.query')
|
|
24
|
+
* // input.instanceId 部署实例键(mall 场景 = mallId;通配激活时由框架解析)
|
|
25
|
+
* // input.config 绑定组五层合并后的连接参数(面板保存的 baseUrl 等)
|
|
26
|
+
* // 返回:实现该服务 Port 的 adapter 实例(模块 src/server/ports 定义)
|
|
27
|
+
* return new MyApiServiceImpl(input);
|
|
28
|
+
* };
|
|
29
|
+
* ctx.integrations?.registerAdapter('my-custom-api', 'my-custom-parking@1', myApiAdapterFactory);
|
|
30
|
+
*/
|
|
31
|
+
export function register(ctx: ServerContext): void {
|
|
32
|
+
// 挂点:多个自定义 API 的 adapter 均在此注册(见上方签名示例)。
|
|
33
|
+
void ctx;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const serverModule = {
|
|
37
|
+
declaration: { moduleId: 'provider-custom' },
|
|
38
|
+
cards: {},
|
|
39
|
+
register,
|
|
40
|
+
} satisfies ServerModule;
|
package/tbox.module.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"name": "provider-custom",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"kind": "business",
|
|
6
|
+
"risk": {
|
|
7
|
+
"level": "low",
|
|
8
|
+
"writeBoundary": "source"
|
|
9
|
+
},
|
|
10
|
+
"distribution": {
|
|
11
|
+
"defaultMode": "codegen"
|
|
12
|
+
},
|
|
13
|
+
"contributes": {
|
|
14
|
+
"handlers": [],
|
|
15
|
+
"tools": [],
|
|
16
|
+
"cards": [],
|
|
17
|
+
"routes": [],
|
|
18
|
+
"pages": [],
|
|
19
|
+
"tabs": [],
|
|
20
|
+
"providers": {
|
|
21
|
+
"slots": []
|
|
22
|
+
},
|
|
23
|
+
"services": []
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"modules": []
|
|
27
|
+
},
|
|
28
|
+
"env": []
|
|
29
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { providerId } from '../src/index';
|
|
3
|
+
import { serverModule } from '../src/server/index';
|
|
4
|
+
|
|
5
|
+
describe('provider-custom 空包(D10 落点)', () => {
|
|
6
|
+
it('serverModule 形状:moduleId + 空 cards + register 可调用', () => {
|
|
7
|
+
expect(serverModule.declaration.moduleId).toBe('provider-custom');
|
|
8
|
+
expect(serverModule.cards).toEqual({});
|
|
9
|
+
expect(typeof serverModule.register).toBe('function');
|
|
10
|
+
expect(providerId).toBe('provider-custom');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('register 零贡献:调用不抛(mock ctx 无 integrations 挂点)', () => {
|
|
14
|
+
const ctx = {} as never;
|
|
15
|
+
expect(() => serverModule.register(ctx)).not.toThrow();
|
|
16
|
+
});
|
|
17
|
+
});
|
package/tsconfig.json
ADDED
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineConfig } from 'tsup';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: {
|
|
5
|
+
index: 'src/index.ts',
|
|
6
|
+
'server/index': 'src/server/index.ts',
|
|
7
|
+
},
|
|
8
|
+
format: ['esm'],
|
|
9
|
+
target: 'node20',
|
|
10
|
+
platform: 'node',
|
|
11
|
+
outDir: 'dist',
|
|
12
|
+
clean: true,
|
|
13
|
+
sourcemap: false,
|
|
14
|
+
// dts worker 以命令行式传参会撞 TS5074(incremental 需单文件 emit 或 tsBuildInfoFile);
|
|
15
|
+
// 声明产物一次性构建无需增量——仅 dts 关闭,typecheck 的增量缓存不受影响。
|
|
16
|
+
dts: { compilerOptions: { incremental: false } },
|
|
17
|
+
external: ['@tbox.cn/app-sdk', '@tbox.cn/app-contracts', 'zod'],
|
|
18
|
+
});
|