@codelockpro/sdk 0.0.1 → 0.1.11
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/LICENSE +34 -0
- package/README.md +125 -0
- package/dist/core/events.d.ts +21 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +45 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/module.d.ts +35 -0
- package/dist/core/module.d.ts.map +1 -0
- package/dist/core/module.js +33 -0
- package/dist/core/module.js.map +1 -0
- package/dist/index.d.ts +103 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/kb.d.ts +105 -0
- package/dist/modules/kb.d.ts.map +1 -0
- package/dist/modules/kb.js +86 -0
- package/dist/modules/kb.js.map +1 -0
- package/package.json +44 -4
- package/src/core/events.ts +65 -0
- package/src/core/module.ts +62 -0
- package/src/index.ts +182 -0
- package/src/modules/kb.ts +205 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
CodeLockPro SDK License
|
|
2
|
+
|
|
3
|
+
Copyright (c) CodeLockPro. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software (the "SDK") is proprietary to CodeLockPro and is licensed,
|
|
6
|
+
not sold. Use of the SDK is permitted only in combination with an active
|
|
7
|
+
CodeLockPro account in good standing.
|
|
8
|
+
|
|
9
|
+
Subject to that condition, you are granted a non-exclusive,
|
|
10
|
+
non-transferable, non-sublicensable, revocable license to install and
|
|
11
|
+
use the SDK, and to integrate it into your own applications, solely for
|
|
12
|
+
the purpose of consuming the CodeLockPro service authorised by your
|
|
13
|
+
account.
|
|
14
|
+
|
|
15
|
+
You may not:
|
|
16
|
+
|
|
17
|
+
1. use the SDK without an active CodeLockPro account;
|
|
18
|
+
2. use the SDK to access any service other than CodeLockPro;
|
|
19
|
+
3. sublicense, sell, rent, lease, or otherwise commercially
|
|
20
|
+
redistribute the SDK as a stand-alone product;
|
|
21
|
+
4. remove or alter any copyright, trademark, or other proprietary
|
|
22
|
+
notices contained in the SDK.
|
|
23
|
+
|
|
24
|
+
The SDK is provided "AS IS", without warranty of any kind, express or
|
|
25
|
+
implied, including but not limited to the warranties of merchantability,
|
|
26
|
+
fitness for a particular purpose, and non-infringement. In no event
|
|
27
|
+
shall CodeLockPro be liable for any claim, damages, or other liability
|
|
28
|
+
arising from, out of, or in connection with the SDK or the use or other
|
|
29
|
+
dealings in the SDK.
|
|
30
|
+
|
|
31
|
+
This license terminates automatically if your CodeLockPro account is
|
|
32
|
+
terminated, suspended, or otherwise becomes inactive. On termination
|
|
33
|
+
you must cease all use of the SDK and remove all copies under your
|
|
34
|
+
control.
|
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# `@codelockpro/sdk`
|
|
2
|
+
|
|
3
|
+
Plain-vanilla, modular **client** SDK — the CodeLockPro client
|
|
4
|
+
framework. Ships with the knowledge base as a built-in module;
|
|
5
|
+
additional modules plug into the same `CodeLockPro` instance through
|
|
6
|
+
the same registration surface.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @codelockpro/sdk
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
> **License.** The SDK is proprietary and may only be used in
|
|
15
|
+
> combination with an active CodeLockPro account. See
|
|
16
|
+
> [`LICENSE`](./LICENSE).
|
|
17
|
+
|
|
18
|
+
## Architecture invariants
|
|
19
|
+
|
|
20
|
+
1. **Modular foundation.** The core has no per-module coupling. KB is
|
|
21
|
+
just the first module registered.
|
|
22
|
+
2. **Server-mediated only.** The SDK is configured with the developer's
|
|
23
|
+
own base URL. **It must never talk directly to the CodeLockPro
|
|
24
|
+
API.** The developer's server is the authoritative middle layer.
|
|
25
|
+
3. **Plain vanilla.** No framework dependency. Hosts (Vue, React,
|
|
26
|
+
Next.js, plain DOM) bind their own state on top of the SDK's data,
|
|
27
|
+
events, and actions.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { CodeLockPro } from "@codelockpro/sdk";
|
|
33
|
+
|
|
34
|
+
const client = new CodeLockPro({ baseUrl: "https://example.com/my-api" });
|
|
35
|
+
|
|
36
|
+
// Data
|
|
37
|
+
const { articles } = await client.kb.getArticles();
|
|
38
|
+
const article = await client.kb.getArticle("how-to-reset-password");
|
|
39
|
+
|
|
40
|
+
// Actions
|
|
41
|
+
await client.kb.trackView(article.id, { slug: article.slug });
|
|
42
|
+
|
|
43
|
+
// Events (subscribe once, in any framework)
|
|
44
|
+
client.on("kb.article.viewed", ({ articleId }) => {
|
|
45
|
+
console.log("viewed", articleId);
|
|
46
|
+
});
|
|
47
|
+
client.on("kb.search.performed", ({ query, count }) => {
|
|
48
|
+
console.log(`${count} results for ${query}`);
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`client.kb` is a convenience accessor for
|
|
53
|
+
`client.module<KnowledgeBaseModule>("kb")`. The core has no
|
|
54
|
+
KB-specific code path.
|
|
55
|
+
|
|
56
|
+
## Registering more modules
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { CodeLockPro, ModuleContext } from "@codelockpro/sdk";
|
|
60
|
+
|
|
61
|
+
function createCheckoutModule(ctx: ModuleContext) {
|
|
62
|
+
return {
|
|
63
|
+
async start(productId: string) {
|
|
64
|
+
const session = await ctx.request<{ url: string }>(
|
|
65
|
+
"/checkout/sessions",
|
|
66
|
+
{ method: "POST", body: JSON.stringify({ productId }) },
|
|
67
|
+
);
|
|
68
|
+
ctx.bus.emit(`${ctx.name}.session.created`, { productId });
|
|
69
|
+
return session;
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const client = new CodeLockPro({
|
|
75
|
+
baseUrl: "https://example.com/my-api",
|
|
76
|
+
modules: [
|
|
77
|
+
["kb", (ctx) => /* … */], // optional — opts out of the default
|
|
78
|
+
["checkout", createCheckoutModule],
|
|
79
|
+
],
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// or after construction:
|
|
83
|
+
client.register("chatbot", createChatbotModule);
|
|
84
|
+
|
|
85
|
+
const checkout = client.module<{ start: (id: string) => Promise<{ url: string }> }>("checkout");
|
|
86
|
+
await checkout.start("pro-monthly");
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Module author contract
|
|
90
|
+
|
|
91
|
+
A module factory is `(ctx: ModuleContext) => MyModule`. The context
|
|
92
|
+
provides:
|
|
93
|
+
|
|
94
|
+
- `ctx.name` — the registered name (`"kb"`, `"checkout"`, …)
|
|
95
|
+
- `ctx.request` — HTTP helper bound to the developer's `baseUrl`
|
|
96
|
+
- `ctx.bus` — shared event bus (`on` / `off` / `emit`)
|
|
97
|
+
|
|
98
|
+
Modules namespace their events as `<ctx.name>.<event>` so listeners stay
|
|
99
|
+
unambiguous when many modules are registered.
|
|
100
|
+
|
|
101
|
+
## Expected server-side proxy (KB)
|
|
102
|
+
|
|
103
|
+
By default the KB module hits `${baseUrl}/kb/articles`,
|
|
104
|
+
`${baseUrl}/kb/articles/{idOrSlug}`, `${baseUrl}/kb/categories`,
|
|
105
|
+
`${baseUrl}/kb/search`, and `POST ${baseUrl}/kb/articles/{id}/views`.
|
|
106
|
+
The developer's server is expected to forward those to the upstream
|
|
107
|
+
CodeLockPro public read API (the PHP companion package
|
|
108
|
+
`codelockpro/sdk` ships ready-made helpers for that step).
|
|
109
|
+
|
|
110
|
+
## Releasing
|
|
111
|
+
|
|
112
|
+
Releases are lock-stepped with the PHP package `codelockpro/sdk` —
|
|
113
|
+
both packages always ship at the same version, and `sdk/js/package.json`
|
|
114
|
+
is the single source of truth for the version number.
|
|
115
|
+
|
|
116
|
+
To cut a release:
|
|
117
|
+
|
|
118
|
+
1. Trigger the **SDK Release** workflow
|
|
119
|
+
(`.github/workflows/sdk-release.yml`) via "Run workflow".
|
|
120
|
+
2. Pick `release_type`: `patch`, `minor`, or `major`.
|
|
121
|
+
3. The workflow bumps `sdk/js/package.json`, commits, tags
|
|
122
|
+
`sdk-v<MAJOR.MINOR.PATCH>`, publishes `@codelockpro/sdk` to npm
|
|
123
|
+
(OIDC trusted publisher with `--provenance`), and pushes the
|
|
124
|
+
`sdk/php/` subtree to the `codelockpro-sdk-php` mirror that
|
|
125
|
+
Packagist watches.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny synchronous event bus shared by all SDK modules.
|
|
3
|
+
*
|
|
4
|
+
* The bus is intentionally minimal — no priority, no async fan-out, no
|
|
5
|
+
* wildcard subscriptions — because the SDK is a thin data/action layer
|
|
6
|
+
* that the host app (Vue, React, Next.js, plain DOM) decorates with its
|
|
7
|
+
* own state-management primitives. Modules emit semantic namespaced
|
|
8
|
+
* events (e.g. ``kb.article.viewed``) and host code subscribes via
|
|
9
|
+
* :meth:`CodeLockPro.on`.
|
|
10
|
+
*
|
|
11
|
+
* The bus has no awareness of which module emits what — it is a
|
|
12
|
+
* module-agnostic primitive owned by the core.
|
|
13
|
+
*/
|
|
14
|
+
export type EventHandler<T = unknown> = (payload: T) => void;
|
|
15
|
+
export interface EventBus {
|
|
16
|
+
on<T = unknown>(event: string, handler: EventHandler<T>): () => void;
|
|
17
|
+
off<T = unknown>(event: string, handler: EventHandler<T>): void;
|
|
18
|
+
emit<T = unknown>(event: string, payload?: T): void;
|
|
19
|
+
}
|
|
20
|
+
export declare function createEventBus(): EventBus;
|
|
21
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/core/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;AAE7D,MAAM,WAAW,QAAQ;IACxB,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;IACrE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;CACpD;AAED,wBAAgB,cAAc,IAAI,QAAQ,CA2CzC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export function createEventBus() {
|
|
2
|
+
const handlers = new Map();
|
|
3
|
+
function on(event, handler) {
|
|
4
|
+
if (typeof event !== "string" || event.length === 0) {
|
|
5
|
+
throw new Error("CodeLockPro.on: event name is required");
|
|
6
|
+
}
|
|
7
|
+
if (typeof handler !== "function") {
|
|
8
|
+
throw new Error("CodeLockPro.on: handler must be a function");
|
|
9
|
+
}
|
|
10
|
+
let set = handlers.get(event);
|
|
11
|
+
if (!set) {
|
|
12
|
+
set = new Set();
|
|
13
|
+
handlers.set(event, set);
|
|
14
|
+
}
|
|
15
|
+
set.add(handler);
|
|
16
|
+
return () => off(event, handler);
|
|
17
|
+
}
|
|
18
|
+
function off(event, handler) {
|
|
19
|
+
const set = handlers.get(event);
|
|
20
|
+
if (!set)
|
|
21
|
+
return;
|
|
22
|
+
set.delete(handler);
|
|
23
|
+
if (set.size === 0)
|
|
24
|
+
handlers.delete(event);
|
|
25
|
+
}
|
|
26
|
+
function emit(event, payload) {
|
|
27
|
+
const set = handlers.get(event);
|
|
28
|
+
if (!set || set.size === 0)
|
|
29
|
+
return;
|
|
30
|
+
// Snapshot so handlers may unsubscribe themselves safely.
|
|
31
|
+
for (const h of Array.from(set)) {
|
|
32
|
+
try {
|
|
33
|
+
h(payload);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
// Never let one handler break another. Surface to the
|
|
37
|
+
// host via ``console.error`` rather than swallowing.
|
|
38
|
+
// eslint-disable-next-line no-console
|
|
39
|
+
console.error(`CodeLockPro: handler for "${event}" threw`, err);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { on, off, emit };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/core/events.ts"],"names":[],"mappings":"AAqBA,MAAM,UAAU,cAAc;IAC7B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA6B,CAAC;IAEtD,SAAS,EAAE,CAAI,KAAa,EAAE,OAAwB;QACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;YACV,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC1B,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,OAAuB,CAAC,CAAC;QACjC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,SAAS,GAAG,CAAI,KAAa,EAAE,OAAwB;QACtD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,GAAG,CAAC,MAAM,CAAC,OAAuB,CAAC,CAAC;QACpC,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;YAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED,SAAS,IAAI,CAAI,KAAa,EAAE,OAAW;QAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QACnC,0DAA0D;QAC1D,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC;gBACJ,CAAC,CAAC,OAAO,CAAC,CAAC;YACZ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,sDAAsD;gBACtD,qDAAqD;gBACrD,sCAAsC;gBACtC,OAAO,CAAC,KAAK,CAAC,6BAA6B,KAAK,SAAS,EAAE,GAAG,CAAC,CAAC;YACjE,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EventBus } from "./events.js";
|
|
2
|
+
/**
|
|
3
|
+
* Module contract.
|
|
4
|
+
*
|
|
5
|
+
* A module is anything the host code wants to attach to a
|
|
6
|
+
* :class:`CodeLockPro` instance. The core does not know about any
|
|
7
|
+
* specific module; modules are produced by user-supplied factories.
|
|
8
|
+
*
|
|
9
|
+
* A factory receives the {@link ModuleContext} and returns the
|
|
10
|
+
* module's public surface (an object). The shape is entirely up to the
|
|
11
|
+
* module author — by convention it exposes data accessors
|
|
12
|
+
* (``getArticles``), actions (``trackView``), and emits semantic
|
|
13
|
+
* events on the shared bus.
|
|
14
|
+
*/
|
|
15
|
+
export interface ModuleContext {
|
|
16
|
+
/** Module name as registered (e.g. ``"kb"``). */
|
|
17
|
+
readonly name: string;
|
|
18
|
+
/** HTTP helper bound to the developer's own ``baseUrl``. */
|
|
19
|
+
request<T = unknown>(path: string, init?: RequestInit): Promise<T>;
|
|
20
|
+
/** Shared event bus. Modules namespace their events as ``"<name>.…"``. */
|
|
21
|
+
readonly bus: EventBus;
|
|
22
|
+
}
|
|
23
|
+
export type ModuleFactory<T = unknown> = (ctx: ModuleContext) => T;
|
|
24
|
+
/**
|
|
25
|
+
* Internal module registry. Exposed via :meth:`CodeLockPro.register` and
|
|
26
|
+
* :meth:`CodeLockPro.module`.
|
|
27
|
+
*/
|
|
28
|
+
export declare class ModuleRegistry {
|
|
29
|
+
private readonly _modules;
|
|
30
|
+
register<T>(name: string, instance: T): T;
|
|
31
|
+
get<T>(name: string): T;
|
|
32
|
+
has(name: string): boolean;
|
|
33
|
+
names(): string[];
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/core/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,aAAa;IAC7B,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnE,0EAA0E;IAC1E,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,aAAa,KAAK,CAAC,CAAC;AAEnE;;;GAGG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IAEvD,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC;IAazC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC;IAQvB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,KAAK,IAAI,MAAM,EAAE;CAGjB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal module registry. Exposed via :meth:`CodeLockPro.register` and
|
|
3
|
+
* :meth:`CodeLockPro.module`.
|
|
4
|
+
*/
|
|
5
|
+
export class ModuleRegistry {
|
|
6
|
+
constructor() {
|
|
7
|
+
this._modules = new Map();
|
|
8
|
+
}
|
|
9
|
+
register(name, instance) {
|
|
10
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
11
|
+
throw new Error("CodeLockPro.register: module name is required");
|
|
12
|
+
}
|
|
13
|
+
if (this._modules.has(name)) {
|
|
14
|
+
throw new Error(`CodeLockPro.register: module "${name}" is already registered`);
|
|
15
|
+
}
|
|
16
|
+
this._modules.set(name, instance);
|
|
17
|
+
return instance;
|
|
18
|
+
}
|
|
19
|
+
get(name) {
|
|
20
|
+
const mod = this._modules.get(name);
|
|
21
|
+
if (mod === undefined) {
|
|
22
|
+
throw new Error(`CodeLockPro.module: no module registered as "${name}"`);
|
|
23
|
+
}
|
|
24
|
+
return mod;
|
|
25
|
+
}
|
|
26
|
+
has(name) {
|
|
27
|
+
return this._modules.has(name);
|
|
28
|
+
}
|
|
29
|
+
names() {
|
|
30
|
+
return Array.from(this._modules.keys());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/core/module.ts"],"names":[],"mappings":"AA0BA;;;GAGG;AACH,MAAM,OAAO,cAAc;IAA3B;QACkB,aAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;IA8BxD,CAAC;IA5BA,QAAQ,CAAI,IAAY,EAAE,QAAW;QACpC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACd,iCAAiC,IAAI,yBAAyB,CAC9D,CAAC;QACH,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClC,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,GAAG,CAAI,IAAY;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,gDAAgD,IAAI,GAAG,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,GAAQ,CAAC;IACjB,CAAC;IAED,GAAG,CAAC,IAAY;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,KAAK;QACJ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;CACD"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@codelockpro/sdk` — the CodeLockPro client framework.
|
|
3
|
+
*
|
|
4
|
+
* A generic, modular foundation developers use to build a complete
|
|
5
|
+
* user experience on their own site by composing CodeLockPro modules.
|
|
6
|
+
* The package ships with a single built-in module (``kb`` — knowledge
|
|
7
|
+
* base) and exposes the same registration surface for any additional
|
|
8
|
+
* modules the developer authors or that ship in future package
|
|
9
|
+
* versions.
|
|
10
|
+
*
|
|
11
|
+
* The core in this file has no knowledge of any specific module.
|
|
12
|
+
* Modules are attached at construction time (or later via
|
|
13
|
+
* :meth:`register`) and are looked up by name through :meth:`module`.
|
|
14
|
+
* Each module gets a shared {@link EventBus} and an HTTP helper bound
|
|
15
|
+
* to the developer's own backend URL.
|
|
16
|
+
*
|
|
17
|
+
* Architecture invariants (see /docs/sdk/README.md):
|
|
18
|
+
*
|
|
19
|
+
* 1. **Modular foundation.** No coupling to any specific module.
|
|
20
|
+
* 2. **Server-mediated access only.** The client SDK is configured
|
|
21
|
+
* with the developer's *own* base URL. It must never talk
|
|
22
|
+
* directly to the CodeLockPro API.
|
|
23
|
+
* 3. **Plain vanilla.** No framework binding. Hosts (Vue / React /
|
|
24
|
+
* Next.js / plain DOM) bind their own state on top of the SDK's
|
|
25
|
+
* data, events, and actions.
|
|
26
|
+
*/
|
|
27
|
+
import { EventHandler } from "./core/events.js";
|
|
28
|
+
import { ModuleFactory } from "./core/module.js";
|
|
29
|
+
import { createKbModule, KnowledgeBaseModule } from "./modules/kb.js";
|
|
30
|
+
export interface CodeLockProConfig {
|
|
31
|
+
/**
|
|
32
|
+
* Base URL of the developer's own backend, e.g.
|
|
33
|
+
* ``https://example.com/my-api``. Module paths are appended to it
|
|
34
|
+
* (``/kb/articles`` etc.). Direct access to ``https://api.codelock.pro``
|
|
35
|
+
* is intentionally not supported — see invariant #2.
|
|
36
|
+
*/
|
|
37
|
+
baseUrl: string;
|
|
38
|
+
/**
|
|
39
|
+
* Modules to register at construction time. Use ``false`` to skip the
|
|
40
|
+
* default registration (KB) and register everything explicitly via
|
|
41
|
+
* :meth:`register`.
|
|
42
|
+
*
|
|
43
|
+
* Each entry is a ``[name, factory]`` tuple — exactly the same shape
|
|
44
|
+
* the registry uses internally — so the same surface registers any
|
|
45
|
+
* future module the same way as KB:
|
|
46
|
+
*
|
|
47
|
+
* new CodeLockPro({
|
|
48
|
+
* baseUrl: "…",
|
|
49
|
+
* modules: [
|
|
50
|
+
* ["kb", createKbModule],
|
|
51
|
+
* ["checkout", createCheckoutModule],
|
|
52
|
+
* ],
|
|
53
|
+
* });
|
|
54
|
+
*/
|
|
55
|
+
modules?: false | Array<[string, ModuleFactory<unknown>]>;
|
|
56
|
+
/** Optional fetch implementation override (tests / Node 16). */
|
|
57
|
+
fetch?: typeof fetch;
|
|
58
|
+
/** Optional default headers merged into every request. */
|
|
59
|
+
headers?: Record<string, string>;
|
|
60
|
+
}
|
|
61
|
+
export declare class CodeLockPro {
|
|
62
|
+
readonly baseUrl: string;
|
|
63
|
+
private readonly _fetch;
|
|
64
|
+
private readonly _headers;
|
|
65
|
+
private readonly _bus;
|
|
66
|
+
private readonly _registry;
|
|
67
|
+
constructor(config: CodeLockProConfig);
|
|
68
|
+
/**
|
|
69
|
+
* Register a module after construction. Modules can be defined by
|
|
70
|
+
* any caller — KB, future first-party modules, and even host-app
|
|
71
|
+
* extensions all use the same entry point.
|
|
72
|
+
*/
|
|
73
|
+
register<T>(name: string, factory: ModuleFactory<T>): T;
|
|
74
|
+
/** Look up a previously registered module by name. */
|
|
75
|
+
module<T = unknown>(name: string): T;
|
|
76
|
+
/** Names of every currently-registered module. */
|
|
77
|
+
moduleNames(): string[];
|
|
78
|
+
/** Subscribe to an event on the shared bus. Returns an unsubscribe fn. */
|
|
79
|
+
on<T = unknown>(event: string, handler: EventHandler<T>): () => void;
|
|
80
|
+
off<T = unknown>(event: string, handler: EventHandler<T>): void;
|
|
81
|
+
emit<T = unknown>(event: string, payload?: T): void;
|
|
82
|
+
/**
|
|
83
|
+
* Convenience accessor for the knowledge-base module. Equivalent to
|
|
84
|
+
* ``client.module<KnowledgeBaseModule>("kb")``. Provided as ergonomic
|
|
85
|
+
* sugar so existing call sites read naturally; it is not part of the
|
|
86
|
+
* core's invariants — if KB is unregistered this throws.
|
|
87
|
+
*/
|
|
88
|
+
get kb(): KnowledgeBaseModule;
|
|
89
|
+
/** Internal HTTP helper. Modules call this rather than fetch directly so
|
|
90
|
+
* cross-cutting concerns (auth, telemetry) can be added in one place. */
|
|
91
|
+
_request<T = unknown>(path: string, init?: RequestInit): Promise<T>;
|
|
92
|
+
}
|
|
93
|
+
export declare class CodeLockProApiError extends Error {
|
|
94
|
+
status: number;
|
|
95
|
+
body: string;
|
|
96
|
+
constructor(status: number, statusText: string, body: string);
|
|
97
|
+
}
|
|
98
|
+
export type { EventBus, EventHandler } from "./core/events.js";
|
|
99
|
+
export type { ModuleContext, ModuleFactory } from "./core/module.js";
|
|
100
|
+
export type { KnowledgeBaseModule, KbArticle, KbCategory, KbListOptions, } from "./modules/kb.js";
|
|
101
|
+
export { createKbModule };
|
|
102
|
+
export default CodeLockPro;
|
|
103
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAA4B,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAiB,aAAa,EAAkB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1D,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,qBAAa,WAAW;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;gBAE/B,MAAM,EAAE,iBAAiB;IA2BrC;;;;OAIG;IACH,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC;IAUvD,sDAAsD;IACtD,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC;IAIpC,kDAAkD;IAClD,WAAW,IAAI,MAAM,EAAE;IAIvB,0EAA0E;IAC1E,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAIpE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAI/D,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI;IAInD;;;;;OAKG;IACH,IAAI,EAAE,IAAI,mBAAmB,CAE5B;IAED;6EACyE;IACnE,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,CAAC,CAAC;CAiB7E;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC1B,MAAM,EAAE,MAAM;IAA6B,IAAI,EAAE,MAAM;gBAAvD,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAS,IAAI,EAAE,MAAM;CAI1E;AAED,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACrE,YAAY,EACX,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,aAAa,GACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,eAAe,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@codelockpro/sdk` — the CodeLockPro client framework.
|
|
3
|
+
*
|
|
4
|
+
* A generic, modular foundation developers use to build a complete
|
|
5
|
+
* user experience on their own site by composing CodeLockPro modules.
|
|
6
|
+
* The package ships with a single built-in module (``kb`` — knowledge
|
|
7
|
+
* base) and exposes the same registration surface for any additional
|
|
8
|
+
* modules the developer authors or that ship in future package
|
|
9
|
+
* versions.
|
|
10
|
+
*
|
|
11
|
+
* The core in this file has no knowledge of any specific module.
|
|
12
|
+
* Modules are attached at construction time (or later via
|
|
13
|
+
* :meth:`register`) and are looked up by name through :meth:`module`.
|
|
14
|
+
* Each module gets a shared {@link EventBus} and an HTTP helper bound
|
|
15
|
+
* to the developer's own backend URL.
|
|
16
|
+
*
|
|
17
|
+
* Architecture invariants (see /docs/sdk/README.md):
|
|
18
|
+
*
|
|
19
|
+
* 1. **Modular foundation.** No coupling to any specific module.
|
|
20
|
+
* 2. **Server-mediated access only.** The client SDK is configured
|
|
21
|
+
* with the developer's *own* base URL. It must never talk
|
|
22
|
+
* directly to the CodeLockPro API.
|
|
23
|
+
* 3. **Plain vanilla.** No framework binding. Hosts (Vue / React /
|
|
24
|
+
* Next.js / plain DOM) bind their own state on top of the SDK's
|
|
25
|
+
* data, events, and actions.
|
|
26
|
+
*/
|
|
27
|
+
import { createEventBus } from "./core/events.js";
|
|
28
|
+
import { ModuleRegistry } from "./core/module.js";
|
|
29
|
+
import { createKbModule } from "./modules/kb.js";
|
|
30
|
+
export class CodeLockPro {
|
|
31
|
+
constructor(config) {
|
|
32
|
+
if (!config || typeof config.baseUrl !== "string" || !config.baseUrl) {
|
|
33
|
+
throw new Error("CodeLockPro: baseUrl is required");
|
|
34
|
+
}
|
|
35
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
36
|
+
this._fetch = config.fetch ?? globalThis.fetch;
|
|
37
|
+
this._headers = config.headers ?? {};
|
|
38
|
+
if (typeof this._fetch !== "function") {
|
|
39
|
+
throw new Error("CodeLockPro: no fetch implementation available");
|
|
40
|
+
}
|
|
41
|
+
this._bus = createEventBus();
|
|
42
|
+
this._registry = new ModuleRegistry();
|
|
43
|
+
// Default registration: KB is module one. Pass ``modules: false``
|
|
44
|
+
// (or override with an explicit list) to opt out — the core
|
|
45
|
+
// itself has no knowledge-base coupling.
|
|
46
|
+
const defaultModules = [
|
|
47
|
+
["kb", createKbModule],
|
|
48
|
+
];
|
|
49
|
+
const toRegister = config.modules === false ? [] : config.modules ?? defaultModules;
|
|
50
|
+
for (const [name, factory] of toRegister) {
|
|
51
|
+
this.register(name, factory);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Register a module after construction. Modules can be defined by
|
|
56
|
+
* any caller — KB, future first-party modules, and even host-app
|
|
57
|
+
* extensions all use the same entry point.
|
|
58
|
+
*/
|
|
59
|
+
register(name, factory) {
|
|
60
|
+
const ctx = {
|
|
61
|
+
name,
|
|
62
|
+
request: this._request.bind(this),
|
|
63
|
+
bus: this._bus,
|
|
64
|
+
};
|
|
65
|
+
const instance = factory(ctx);
|
|
66
|
+
return this._registry.register(name, instance);
|
|
67
|
+
}
|
|
68
|
+
/** Look up a previously registered module by name. */
|
|
69
|
+
module(name) {
|
|
70
|
+
return this._registry.get(name);
|
|
71
|
+
}
|
|
72
|
+
/** Names of every currently-registered module. */
|
|
73
|
+
moduleNames() {
|
|
74
|
+
return this._registry.names();
|
|
75
|
+
}
|
|
76
|
+
/** Subscribe to an event on the shared bus. Returns an unsubscribe fn. */
|
|
77
|
+
on(event, handler) {
|
|
78
|
+
return this._bus.on(event, handler);
|
|
79
|
+
}
|
|
80
|
+
off(event, handler) {
|
|
81
|
+
this._bus.off(event, handler);
|
|
82
|
+
}
|
|
83
|
+
emit(event, payload) {
|
|
84
|
+
this._bus.emit(event, payload);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Convenience accessor for the knowledge-base module. Equivalent to
|
|
88
|
+
* ``client.module<KnowledgeBaseModule>("kb")``. Provided as ergonomic
|
|
89
|
+
* sugar so existing call sites read naturally; it is not part of the
|
|
90
|
+
* core's invariants — if KB is unregistered this throws.
|
|
91
|
+
*/
|
|
92
|
+
get kb() {
|
|
93
|
+
return this.module("kb");
|
|
94
|
+
}
|
|
95
|
+
/** Internal HTTP helper. Modules call this rather than fetch directly so
|
|
96
|
+
* cross-cutting concerns (auth, telemetry) can be added in one place. */
|
|
97
|
+
async _request(path, init = {}) {
|
|
98
|
+
const url = `${this.baseUrl}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
99
|
+
const res = await this._fetch(url, {
|
|
100
|
+
...init,
|
|
101
|
+
headers: {
|
|
102
|
+
Accept: "application/json",
|
|
103
|
+
...this._headers,
|
|
104
|
+
...(init.headers || {}),
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
if (!res.ok) {
|
|
108
|
+
const text = await res.text().catch(() => "");
|
|
109
|
+
throw new CodeLockProApiError(res.status, res.statusText, text);
|
|
110
|
+
}
|
|
111
|
+
if (res.status === 204)
|
|
112
|
+
return undefined;
|
|
113
|
+
return (await res.json());
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
export class CodeLockProApiError extends Error {
|
|
117
|
+
constructor(status, statusText, body) {
|
|
118
|
+
super(`CodeLockPro API ${status} ${statusText}: ${body}`);
|
|
119
|
+
this.status = status;
|
|
120
|
+
this.body = body;
|
|
121
|
+
this.name = "CodeLockProApiError";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export { createKbModule };
|
|
125
|
+
export default CodeLockPro;
|
|
126
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge base — the built-in module of the CodeLockPro SDK.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the developer's server-side proxy of the unauthenticated public
|
|
5
|
+
* KB endpoints. This module is **not** privileged inside the SDK core —
|
|
6
|
+
* it uses the same {@link ModuleFactory} contract any additional
|
|
7
|
+
* module the developer registers will use.
|
|
8
|
+
*
|
|
9
|
+
* Default expected paths under the configured ``baseUrl`` (override via
|
|
10
|
+
* ``options.basePath`` if your proxy mounts elsewhere):
|
|
11
|
+
*
|
|
12
|
+
* GET {basePath}/articles → list articles
|
|
13
|
+
* GET {basePath}/articles/{idOrSlug} → single article
|
|
14
|
+
* GET {basePath}/categories → list categories
|
|
15
|
+
* GET {basePath}/search?q=… → full-text search
|
|
16
|
+
* POST {basePath}/articles/{id}/track-view → record a view (action)
|
|
17
|
+
*
|
|
18
|
+
* Events emitted on the shared bus (subscribe via ``client.on(...)``):
|
|
19
|
+
*
|
|
20
|
+
* ``kb.article.viewed`` — payload ``{ articleId: string, slug?: string }``
|
|
21
|
+
* ``kb.search.performed`` — payload ``{ query: string, count: number }``
|
|
22
|
+
*
|
|
23
|
+
* Custom events from host apps may follow the same ``kb.*`` namespace.
|
|
24
|
+
*/
|
|
25
|
+
import type { ModuleFactory } from "../core/module.js";
|
|
26
|
+
export interface KbArticle {
|
|
27
|
+
id: string;
|
|
28
|
+
application_id: string;
|
|
29
|
+
category_id: string | null;
|
|
30
|
+
developer_id: string;
|
|
31
|
+
slug: string;
|
|
32
|
+
title: string;
|
|
33
|
+
excerpt: string | null;
|
|
34
|
+
content?: string;
|
|
35
|
+
status: "draft" | "published";
|
|
36
|
+
published_at: string | null;
|
|
37
|
+
created_at: string | null;
|
|
38
|
+
updated_at: string | null;
|
|
39
|
+
}
|
|
40
|
+
export interface KbCategory {
|
|
41
|
+
id: string;
|
|
42
|
+
application_id: string;
|
|
43
|
+
developer_id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
slug: string;
|
|
46
|
+
description: string | null;
|
|
47
|
+
created_at: string | null;
|
|
48
|
+
updated_at: string | null;
|
|
49
|
+
}
|
|
50
|
+
export interface KbListOptions {
|
|
51
|
+
categoryId?: string;
|
|
52
|
+
categorySlug?: string;
|
|
53
|
+
limit?: number;
|
|
54
|
+
startingAfter?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface KbArticleViewedPayload {
|
|
57
|
+
articleId: string;
|
|
58
|
+
slug?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface KbSearchPerformedPayload {
|
|
61
|
+
query: string;
|
|
62
|
+
count: number;
|
|
63
|
+
}
|
|
64
|
+
export interface KnowledgeBaseModule {
|
|
65
|
+
getArticles(opts?: KbListOptions): Promise<{
|
|
66
|
+
articles: KbArticle[];
|
|
67
|
+
}>;
|
|
68
|
+
getArticle(idOrSlug: string): Promise<KbArticle>;
|
|
69
|
+
getCategories(): Promise<{
|
|
70
|
+
categories: KbCategory[];
|
|
71
|
+
}>;
|
|
72
|
+
search(query: string, limit?: number): Promise<{
|
|
73
|
+
query: string;
|
|
74
|
+
articles: KbArticle[];
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Record a view of an article via the developer's proxy and emit
|
|
78
|
+
* ``kb.article.viewed`` on the shared event bus. Errors from the
|
|
79
|
+
* server are swallowed so view-tracking never blocks rendering;
|
|
80
|
+
* the bus event always fires.
|
|
81
|
+
*/
|
|
82
|
+
trackView(articleId: string, opts?: {
|
|
83
|
+
slug?: string;
|
|
84
|
+
}): Promise<void>;
|
|
85
|
+
/** Subscribe to an event scoped to this module (``kb.<event>``). */
|
|
86
|
+
on<T = unknown>(event: string, handler: (payload: T) => void): () => void;
|
|
87
|
+
off<T = unknown>(event: string, handler: (payload: T) => void): void;
|
|
88
|
+
}
|
|
89
|
+
export interface KbModuleOptions {
|
|
90
|
+
/** Override the proxy mount-point (default: ``/kb``). */
|
|
91
|
+
basePath?: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Module factory. Conforms to {@link ModuleFactory} — the SDK core treats
|
|
95
|
+
* KB exactly like any other module.
|
|
96
|
+
*
|
|
97
|
+
* const client = new CodeLockPro({
|
|
98
|
+
* baseUrl: "https://example.com/my-api",
|
|
99
|
+
* modules: [["kb", createKbModule]],
|
|
100
|
+
* });
|
|
101
|
+
*/
|
|
102
|
+
export declare const createKbModule: ModuleFactory<KnowledgeBaseModule>;
|
|
103
|
+
/** Variant that accepts module-specific options (e.g. a custom basePath). */
|
|
104
|
+
export declare function createKbModuleWith(options: KbModuleOptions): ModuleFactory<KnowledgeBaseModule>;
|
|
105
|
+
//# sourceMappingURL=kb.d.ts.map
|