@kosdev-code/kos-api-levels 2.1.39 → 3.0.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/deprecation.d.ts.map +1 -1
- package/index.cjs +78 -1
- package/index.cjs.map +1 -1
- package/index.d.ts.map +1 -1
- package/index.js +59 -49
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/registry.d.ts +0 -1
- package/registry.d.ts.map +1 -1
- package/runtime.d.ts +0 -1
- package/runtime.d.ts.map +1 -1
- package/types.d.ts.map +1 -1
package/deprecation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deprecation.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"deprecation.d.ts","sourceRoot":"","sources":["../../../packages/kos-api-levels/src/deprecation.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACpB,IAAI,CAUN"}
|
package/index.cjs
CHANGED
|
@@ -1,2 +1,79 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const _warned = /* @__PURE__ */ new Set();
|
|
4
|
+
function warnDeprecated(apiName, serviceId, deprecatedAtLevel, replacement, removeAtLevel) {
|
|
5
|
+
if (typeof process !== "undefined" && process.env["NODE_ENV"] === "production") {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
if (_warned.has(apiName)) return;
|
|
9
|
+
_warned.add(apiName);
|
|
10
|
+
console.warn(
|
|
11
|
+
`[KOS] "${apiName}" is deprecated since ${serviceId} level ${deprecatedAtLevel}. Use "${replacement}" instead. Will be removed at level ${removeAtLevel}.`
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
const _registry = {};
|
|
15
|
+
function registerApiLevels(levels) {
|
|
16
|
+
Object.assign(_registry, levels);
|
|
17
|
+
}
|
|
18
|
+
function getRegistry() {
|
|
19
|
+
return _registry;
|
|
20
|
+
}
|
|
21
|
+
function getApiLevel(service) {
|
|
22
|
+
return getRegistry()[service] ?? 0;
|
|
23
|
+
}
|
|
24
|
+
function hasApiLevel(service, minLevel) {
|
|
25
|
+
return getApiLevel(service) >= minLevel;
|
|
26
|
+
}
|
|
27
|
+
function requireApiLevel(service, minLevel) {
|
|
28
|
+
const actual = getApiLevel(service);
|
|
29
|
+
if (actual < minLevel) {
|
|
30
|
+
const actualLabel = actual === 0 ? "not registered" : String(actual);
|
|
31
|
+
throw new Error(
|
|
32
|
+
`[KOS] API level requirement not met for "${service}": required ${minLevel}, actual ${actualLabel}`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function getAllApiLevels() {
|
|
37
|
+
return getRegistry();
|
|
38
|
+
}
|
|
39
|
+
function checkApiLevels(requirements) {
|
|
40
|
+
const details = {};
|
|
41
|
+
let satisfied = true;
|
|
42
|
+
for (const [service, required] of Object.entries(requirements)) {
|
|
43
|
+
if (required === void 0) continue;
|
|
44
|
+
const actual = getApiLevel(service);
|
|
45
|
+
const ok = actual >= required;
|
|
46
|
+
details[service] = { required, actual, ok };
|
|
47
|
+
if (!ok) satisfied = false;
|
|
48
|
+
}
|
|
49
|
+
return { satisfied, details };
|
|
50
|
+
}
|
|
51
|
+
function checkCompatibility(requirements) {
|
|
52
|
+
const ddkLevel = getApiLevel("ddk.compat");
|
|
53
|
+
const minPluginLevel = getApiLevel("ddk.compat.min-plugin");
|
|
54
|
+
if (requirements.pluginRequiresDdkLevel > ddkLevel) {
|
|
55
|
+
const ddkLabel = ddkLevel === 0 ? "not registered" : String(ddkLevel);
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
reason: "too-new-plugin",
|
|
59
|
+
message: `[KOS] Plugin requires DDK level ${requirements.pluginRequiresDdkLevel}, but host provides level ${ddkLabel}.`
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (minPluginLevel > 0 && requirements.pluginLevel < minPluginLevel) {
|
|
63
|
+
return {
|
|
64
|
+
ok: false,
|
|
65
|
+
reason: "too-old-plugin",
|
|
66
|
+
message: `[KOS] Plugin level ${requirements.pluginLevel} is below the host's minimum accepted plugin level ${minPluginLevel}.`
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return { ok: true, reason: "ok" };
|
|
70
|
+
}
|
|
71
|
+
exports.checkApiLevels = checkApiLevels;
|
|
72
|
+
exports.checkCompatibility = checkCompatibility;
|
|
73
|
+
exports.getAllApiLevels = getAllApiLevels;
|
|
74
|
+
exports.getApiLevel = getApiLevel;
|
|
75
|
+
exports.hasApiLevel = hasApiLevel;
|
|
76
|
+
exports.registerApiLevels = registerApiLevels;
|
|
77
|
+
exports.requireApiLevel = requireApiLevel;
|
|
78
|
+
exports.warnDeprecated = warnDeprecated;
|
|
2
79
|
//# sourceMappingURL=index.cjs.map
|
package/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../packages/kos-api-levels/src/deprecation.ts","../../../packages/kos-api-levels/src/registry.ts","../../../packages/kos-api-levels/src/runtime.ts"],"sourcesContent":["const _warned = new Set<string>();\n\n/**\n * Emits a one-time console warning in non-production environments when a\n * deprecated API is used.\n *\n * @param apiName - The name of the deprecated API (e.g. `@kosSubscribe`)\n * @param serviceId - The service the API belongs to (e.g. `core.subscribe`)\n * @param deprecatedAtLevel - The API level at which this API was deprecated\n * @param replacement - The recommended replacement (e.g. `@kosTopicHandler`)\n * @param removeAtLevel - The API level at which this API will be removed\n */\nexport function warnDeprecated(\n apiName: string,\n serviceId: string,\n deprecatedAtLevel: number,\n replacement: string,\n removeAtLevel: number\n): void {\n if (typeof process !== 'undefined' && process.env['NODE_ENV'] === 'production') {\n return;\n }\n if (_warned.has(apiName)) return;\n _warned.add(apiName);\n console.warn(\n `[KOS] \"${apiName}\" is deprecated since ${serviceId} level ${deprecatedAtLevel}. ` +\n `Use \"${replacement}\" instead. Will be removed at level ${removeAtLevel}.`\n );\n}\n","import type { ApiLevelMap } from './types';\n\nconst _registry: ApiLevelMap = {};\n\n/**\n * Registers API levels for an SDK package. Each SDK package calls this on\n * import to populate the in-memory registry. Works in browser and Node.js.\n *\n * Phase 1: called manually from each package's index.ts.\n * Phase 2: generated automatically by the JSDoc scanner at build time.\n */\nexport function registerApiLevels(levels: ApiLevelMap): void {\n Object.assign(_registry, levels);\n}\n\nexport function getRegistry(): Readonly<ApiLevelMap> {\n return _registry;\n}\n","import type { ServiceId, ApiLevelMap, CheckResult, PluginCompatRequirements, CompatResult } from './types';\nimport { getRegistry } from './registry';\n\n/**\n * Returns the current API level for a service.\n * Returns 0 if the service has not been registered.\n */\nexport function getApiLevel(service: ServiceId): number {\n return getRegistry()[service] ?? 0;\n}\n\n/**\n * Returns true if the registered level for a service meets the minimum requirement.\n */\nexport function hasApiLevel(service: ServiceId, minLevel: number): boolean {\n return getApiLevel(service) >= minLevel;\n}\n\n/**\n * Throws if the registered level for a service does not meet the minimum requirement.\n */\nexport function requireApiLevel(service: ServiceId, minLevel: number): void {\n const actual = getApiLevel(service);\n if (actual < minLevel) {\n const actualLabel = actual === 0 ? 'not registered' : String(actual);\n throw new Error(\n `[KOS] API level requirement not met for \"${service}\": required ${minLevel}, actual ${actualLabel}`\n );\n }\n}\n\n/**\n * Returns all registered API levels. Useful for diagnostics and logging.\n */\nexport function getAllApiLevels(): Readonly<ApiLevelMap> {\n return getRegistry();\n}\n\n/**\n * Checks multiple service requirements in a single call.\n */\nexport function checkApiLevels(requirements: Partial<ApiLevelMap>): CheckResult {\n const details: CheckResult['details'] = {};\n let satisfied = true;\n\n for (const [service, required] of Object.entries(requirements)) {\n if (required === undefined) continue;\n const actual = getApiLevel(service);\n const ok = actual >= required;\n details[service] = { required, actual, ok };\n if (!ok) satisfied = false;\n }\n\n return { satisfied, details };\n}\n\n/**\n * Checks whether a DDK plugin is compatible with the current DDK host.\n *\n * The DDK host registers two services at startup:\n * - `ddk.compat` — the current DDK API level (what it provides)\n * - `ddk.compat.min-plugin` — the oldest plugin level this host still accepts\n *\n * A plugin passes its own requirements:\n * - `pluginRequiresDdkLevel` — minimum DDK level the plugin needs\n * - `pluginLevel` — the API level of the plugin itself\n *\n * Both directions are checked:\n * - Plugin too new for host: `pluginRequiresDdkLevel > ddk.compat`\n * - Plugin too old for host: `pluginLevel < ddk.compat.min-plugin`\n */\nexport function checkCompatibility(requirements: PluginCompatRequirements): CompatResult {\n const ddkLevel = getApiLevel('ddk.compat');\n const minPluginLevel = getApiLevel('ddk.compat.min-plugin');\n\n if (requirements.pluginRequiresDdkLevel > ddkLevel) {\n const ddkLabel = ddkLevel === 0 ? 'not registered' : String(ddkLevel);\n return {\n ok: false,\n reason: 'too-new-plugin',\n message:\n `[KOS] Plugin requires DDK level ${requirements.pluginRequiresDdkLevel}, ` +\n `but host provides level ${ddkLabel}.`,\n };\n }\n\n if (minPluginLevel > 0 && requirements.pluginLevel < minPluginLevel) {\n return {\n ok: false,\n reason: 'too-old-plugin',\n message:\n `[KOS] Plugin level ${requirements.pluginLevel} is below the host's minimum ` +\n `accepted plugin level ${minPluginLevel}.`,\n };\n }\n\n return { ok: true, reason: 'ok' };\n}\n"],"names":[],"mappings":";;AAAA,MAAM,8BAAc,IAAA;AAYb,SAAS,eACd,SACA,WACA,mBACA,aACA,eACM;AACN,MAAI,OAAO,YAAY,eAAe,QAAQ,IAAI,UAAU,MAAM,cAAc;AAC9E;AAAA,EACF;AACA,MAAI,QAAQ,IAAI,OAAO,EAAG;AAC1B,UAAQ,IAAI,OAAO;AACnB,UAAQ;AAAA,IACN,UAAU,OAAO,yBAAyB,SAAS,UAAU,iBAAiB,UACpE,WAAW,uCAAuC,aAAa;AAAA,EAAA;AAE7E;AC1BA,MAAM,YAAyB,CAAA;AASxB,SAAS,kBAAkB,QAA2B;AAC3D,SAAO,OAAO,WAAW,MAAM;AACjC;AAEO,SAAS,cAAqC;AACnD,SAAO;AACT;ACVO,SAAS,YAAY,SAA4B;AACtD,SAAO,YAAA,EAAc,OAAO,KAAK;AACnC;AAKO,SAAS,YAAY,SAAoB,UAA2B;AACzE,SAAO,YAAY,OAAO,KAAK;AACjC;AAKO,SAAS,gBAAgB,SAAoB,UAAwB;AAC1E,QAAM,SAAS,YAAY,OAAO;AAClC,MAAI,SAAS,UAAU;AACrB,UAAM,cAAc,WAAW,IAAI,mBAAmB,OAAO,MAAM;AACnE,UAAM,IAAI;AAAA,MACR,4CAA4C,OAAO,eAAe,QAAQ,YAAY,WAAW;AAAA,IAAA;AAAA,EAErG;AACF;AAKO,SAAS,kBAAyC;AACvD,SAAO,YAAA;AACT;AAKO,SAAS,eAAe,cAAiD;AAC9E,QAAM,UAAkC,CAAA;AACxC,MAAI,YAAY;AAEhB,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,YAAY,GAAG;AAC9D,QAAI,aAAa,OAAW;AAC5B,UAAM,SAAS,YAAY,OAAO;AAClC,UAAM,KAAK,UAAU;AACrB,YAAQ,OAAO,IAAI,EAAE,UAAU,QAAQ,GAAA;AACvC,QAAI,CAAC,GAAI,aAAY;AAAA,EACvB;AAEA,SAAO,EAAE,WAAW,QAAA;AACtB;AAiBO,SAAS,mBAAmB,cAAsD;AACvF,QAAM,WAAW,YAAY,YAAY;AACzC,QAAM,iBAAiB,YAAY,uBAAuB;AAE1D,MAAI,aAAa,yBAAyB,UAAU;AAClD,UAAM,WAAW,aAAa,IAAI,mBAAmB,OAAO,QAAQ;AACpE,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,SACE,mCAAmC,aAAa,sBAAsB,6BAC3C,QAAQ;AAAA,IAAA;AAAA,EAEzC;AAEA,MAAI,iBAAiB,KAAK,aAAa,cAAc,gBAAgB;AACnE,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,SACE,sBAAsB,aAAa,WAAW,sDACrB,cAAc;AAAA,IAAA;AAAA,EAE7C;AAEA,SAAO,EAAE,IAAI,MAAM,QAAQ,KAAA;AAC7B;;;;;;;;;"}
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../packages/kos-api-levels/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,WAAW,EACX,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACxB,SAAS,GACV,MAAM,SAAS,CAAC"}
|
package/index.js
CHANGED
|
@@ -1,69 +1,79 @@
|
|
|
1
|
-
const
|
|
2
|
-
function
|
|
3
|
-
typeof process
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
const _warned = /* @__PURE__ */ new Set();
|
|
2
|
+
function warnDeprecated(apiName, serviceId, deprecatedAtLevel, replacement, removeAtLevel) {
|
|
3
|
+
if (typeof process !== "undefined" && process.env["NODE_ENV"] === "production") {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
if (_warned.has(apiName)) return;
|
|
7
|
+
_warned.add(apiName);
|
|
8
|
+
console.warn(
|
|
9
|
+
`[KOS] "${apiName}" is deprecated since ${serviceId} level ${deprecatedAtLevel}. Use "${replacement}" instead. Will be removed at level ${removeAtLevel}.`
|
|
10
|
+
);
|
|
6
11
|
}
|
|
7
|
-
const
|
|
8
|
-
function
|
|
9
|
-
Object.assign(
|
|
12
|
+
const _registry = {};
|
|
13
|
+
function registerApiLevels(levels) {
|
|
14
|
+
Object.assign(_registry, levels);
|
|
10
15
|
}
|
|
11
|
-
function
|
|
12
|
-
return
|
|
16
|
+
function getRegistry() {
|
|
17
|
+
return _registry;
|
|
13
18
|
}
|
|
14
|
-
function
|
|
15
|
-
return
|
|
19
|
+
function getApiLevel(service) {
|
|
20
|
+
return getRegistry()[service] ?? 0;
|
|
16
21
|
}
|
|
17
|
-
function
|
|
18
|
-
return
|
|
22
|
+
function hasApiLevel(service, minLevel) {
|
|
23
|
+
return getApiLevel(service) >= minLevel;
|
|
19
24
|
}
|
|
20
|
-
function
|
|
21
|
-
const
|
|
22
|
-
if (
|
|
23
|
-
const
|
|
25
|
+
function requireApiLevel(service, minLevel) {
|
|
26
|
+
const actual = getApiLevel(service);
|
|
27
|
+
if (actual < minLevel) {
|
|
28
|
+
const actualLabel = actual === 0 ? "not registered" : String(actual);
|
|
24
29
|
throw new Error(
|
|
25
|
-
`[KOS] API level requirement not met for "${
|
|
30
|
+
`[KOS] API level requirement not met for "${service}": required ${minLevel}, actual ${actualLabel}`
|
|
26
31
|
);
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
|
-
function
|
|
30
|
-
return
|
|
34
|
+
function getAllApiLevels() {
|
|
35
|
+
return getRegistry();
|
|
31
36
|
}
|
|
32
|
-
function
|
|
33
|
-
const
|
|
34
|
-
let
|
|
35
|
-
for (const [
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
37
|
+
function checkApiLevels(requirements) {
|
|
38
|
+
const details = {};
|
|
39
|
+
let satisfied = true;
|
|
40
|
+
for (const [service, required] of Object.entries(requirements)) {
|
|
41
|
+
if (required === void 0) continue;
|
|
42
|
+
const actual = getApiLevel(service);
|
|
43
|
+
const ok = actual >= required;
|
|
44
|
+
details[service] = { required, actual, ok };
|
|
45
|
+
if (!ok) satisfied = false;
|
|
40
46
|
}
|
|
41
|
-
return { satisfied
|
|
47
|
+
return { satisfied, details };
|
|
42
48
|
}
|
|
43
|
-
function
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
function checkCompatibility(requirements) {
|
|
50
|
+
const ddkLevel = getApiLevel("ddk.compat");
|
|
51
|
+
const minPluginLevel = getApiLevel("ddk.compat.min-plugin");
|
|
52
|
+
if (requirements.pluginRequiresDdkLevel > ddkLevel) {
|
|
53
|
+
const ddkLabel = ddkLevel === 0 ? "not registered" : String(ddkLevel);
|
|
47
54
|
return {
|
|
48
|
-
ok:
|
|
55
|
+
ok: false,
|
|
49
56
|
reason: "too-new-plugin",
|
|
50
|
-
message: `[KOS] Plugin requires DDK level ${
|
|
57
|
+
message: `[KOS] Plugin requires DDK level ${requirements.pluginRequiresDdkLevel}, but host provides level ${ddkLabel}.`
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (minPluginLevel > 0 && requirements.pluginLevel < minPluginLevel) {
|
|
61
|
+
return {
|
|
62
|
+
ok: false,
|
|
63
|
+
reason: "too-old-plugin",
|
|
64
|
+
message: `[KOS] Plugin level ${requirements.pluginLevel} is below the host's minimum accepted plugin level ${minPluginLevel}.`
|
|
51
65
|
};
|
|
52
66
|
}
|
|
53
|
-
return
|
|
54
|
-
ok: !1,
|
|
55
|
-
reason: "too-old-plugin",
|
|
56
|
-
message: `[KOS] Plugin level ${e.pluginLevel} is below the host's minimum accepted plugin level ${t}.`
|
|
57
|
-
} : { ok: !0, reason: "ok" };
|
|
67
|
+
return { ok: true, reason: "ok" };
|
|
58
68
|
}
|
|
59
69
|
export {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
checkApiLevels,
|
|
71
|
+
checkCompatibility,
|
|
72
|
+
getAllApiLevels,
|
|
73
|
+
getApiLevel,
|
|
74
|
+
hasApiLevel,
|
|
75
|
+
registerApiLevels,
|
|
76
|
+
requireApiLevel,
|
|
77
|
+
warnDeprecated
|
|
68
78
|
};
|
|
69
79
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../packages/kos-api-levels/src/deprecation.ts","../../../packages/kos-api-levels/src/registry.ts","../../../packages/kos-api-levels/src/runtime.ts"],"sourcesContent":["const _warned = new Set<string>();\n\n/**\n * Emits a one-time console warning in non-production environments when a\n * deprecated API is used.\n *\n * @param apiName - The name of the deprecated API (e.g. `@kosSubscribe`)\n * @param serviceId - The service the API belongs to (e.g. `core.subscribe`)\n * @param deprecatedAtLevel - The API level at which this API was deprecated\n * @param replacement - The recommended replacement (e.g. `@kosTopicHandler`)\n * @param removeAtLevel - The API level at which this API will be removed\n */\nexport function warnDeprecated(\n apiName: string,\n serviceId: string,\n deprecatedAtLevel: number,\n replacement: string,\n removeAtLevel: number\n): void {\n if (typeof process !== 'undefined' && process.env['NODE_ENV'] === 'production') {\n return;\n }\n if (_warned.has(apiName)) return;\n _warned.add(apiName);\n console.warn(\n `[KOS] \"${apiName}\" is deprecated since ${serviceId} level ${deprecatedAtLevel}. ` +\n `Use \"${replacement}\" instead. Will be removed at level ${removeAtLevel}.`\n );\n}\n","import type { ApiLevelMap } from './types';\n\nconst _registry: ApiLevelMap = {};\n\n/**\n * Registers API levels for an SDK package. Each SDK package calls this on\n * import to populate the in-memory registry. Works in browser and Node.js.\n *\n * Phase 1: called manually from each package's index.ts.\n * Phase 2: generated automatically by the JSDoc scanner at build time.\n */\nexport function registerApiLevels(levels: ApiLevelMap): void {\n Object.assign(_registry, levels);\n}\n\nexport function getRegistry(): Readonly<ApiLevelMap> {\n return _registry;\n}\n","import type { ServiceId, ApiLevelMap, CheckResult, PluginCompatRequirements, CompatResult } from './types';\nimport { getRegistry } from './registry';\n\n/**\n * Returns the current API level for a service.\n * Returns 0 if the service has not been registered.\n */\nexport function getApiLevel(service: ServiceId): number {\n return getRegistry()[service] ?? 0;\n}\n\n/**\n * Returns true if the registered level for a service meets the minimum requirement.\n */\nexport function hasApiLevel(service: ServiceId, minLevel: number): boolean {\n return getApiLevel(service) >= minLevel;\n}\n\n/**\n * Throws if the registered level for a service does not meet the minimum requirement.\n */\nexport function requireApiLevel(service: ServiceId, minLevel: number): void {\n const actual = getApiLevel(service);\n if (actual < minLevel) {\n const actualLabel = actual === 0 ? 'not registered' : String(actual);\n throw new Error(\n `[KOS] API level requirement not met for \"${service}\": required ${minLevel}, actual ${actualLabel}`\n );\n }\n}\n\n/**\n * Returns all registered API levels. Useful for diagnostics and logging.\n */\nexport function getAllApiLevels(): Readonly<ApiLevelMap> {\n return getRegistry();\n}\n\n/**\n * Checks multiple service requirements in a single call.\n */\nexport function checkApiLevels(requirements: Partial<ApiLevelMap>): CheckResult {\n const details: CheckResult['details'] = {};\n let satisfied = true;\n\n for (const [service, required] of Object.entries(requirements)) {\n if (required === undefined) continue;\n const actual = getApiLevel(service);\n const ok = actual >= required;\n details[service] = { required, actual, ok };\n if (!ok) satisfied = false;\n }\n\n return { satisfied, details };\n}\n\n/**\n * Checks whether a DDK plugin is compatible with the current DDK host.\n *\n * The DDK host registers two services at startup:\n * - `ddk.compat` — the current DDK API level (what it provides)\n * - `ddk.compat.min-plugin` — the oldest plugin level this host still accepts\n *\n * A plugin passes its own requirements:\n * - `pluginRequiresDdkLevel` — minimum DDK level the plugin needs\n * - `pluginLevel` — the API level of the plugin itself\n *\n * Both directions are checked:\n * - Plugin too new for host: `pluginRequiresDdkLevel > ddk.compat`\n * - Plugin too old for host: `pluginLevel < ddk.compat.min-plugin`\n */\nexport function checkCompatibility(requirements: PluginCompatRequirements): CompatResult {\n const ddkLevel = getApiLevel('ddk.compat');\n const minPluginLevel = getApiLevel('ddk.compat.min-plugin');\n\n if (requirements.pluginRequiresDdkLevel > ddkLevel) {\n const ddkLabel = ddkLevel === 0 ? 'not registered' : String(ddkLevel);\n return {\n ok: false,\n reason: 'too-new-plugin',\n message:\n `[KOS] Plugin requires DDK level ${requirements.pluginRequiresDdkLevel}, ` +\n `but host provides level ${ddkLabel}.`,\n };\n }\n\n if (minPluginLevel > 0 && requirements.pluginLevel < minPluginLevel) {\n return {\n ok: false,\n reason: 'too-old-plugin',\n message:\n `[KOS] Plugin level ${requirements.pluginLevel} is below the host's minimum ` +\n `accepted plugin level ${minPluginLevel}.`,\n };\n }\n\n return { ok: true, reason: 'ok' };\n}\n"],"names":[],"mappings":"AAAA,MAAM,8BAAc,IAAA;AAYb,SAAS,eACd,SACA,WACA,mBACA,aACA,eACM;AACN,MAAI,OAAO,YAAY,eAAe,QAAQ,IAAI,UAAU,MAAM,cAAc;AAC9E;AAAA,EACF;AACA,MAAI,QAAQ,IAAI,OAAO,EAAG;AAC1B,UAAQ,IAAI,OAAO;AACnB,UAAQ;AAAA,IACN,UAAU,OAAO,yBAAyB,SAAS,UAAU,iBAAiB,UACpE,WAAW,uCAAuC,aAAa;AAAA,EAAA;AAE7E;AC1BA,MAAM,YAAyB,CAAA;AASxB,SAAS,kBAAkB,QAA2B;AAC3D,SAAO,OAAO,WAAW,MAAM;AACjC;AAEO,SAAS,cAAqC;AACnD,SAAO;AACT;ACVO,SAAS,YAAY,SAA4B;AACtD,SAAO,YAAA,EAAc,OAAO,KAAK;AACnC;AAKO,SAAS,YAAY,SAAoB,UAA2B;AACzE,SAAO,YAAY,OAAO,KAAK;AACjC;AAKO,SAAS,gBAAgB,SAAoB,UAAwB;AAC1E,QAAM,SAAS,YAAY,OAAO;AAClC,MAAI,SAAS,UAAU;AACrB,UAAM,cAAc,WAAW,IAAI,mBAAmB,OAAO,MAAM;AACnE,UAAM,IAAI;AAAA,MACR,4CAA4C,OAAO,eAAe,QAAQ,YAAY,WAAW;AAAA,IAAA;AAAA,EAErG;AACF;AAKO,SAAS,kBAAyC;AACvD,SAAO,YAAA;AACT;AAKO,SAAS,eAAe,cAAiD;AAC9E,QAAM,UAAkC,CAAA;AACxC,MAAI,YAAY;AAEhB,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,YAAY,GAAG;AAC9D,QAAI,aAAa,OAAW;AAC5B,UAAM,SAAS,YAAY,OAAO;AAClC,UAAM,KAAK,UAAU;AACrB,YAAQ,OAAO,IAAI,EAAE,UAAU,QAAQ,GAAA;AACvC,QAAI,CAAC,GAAI,aAAY;AAAA,EACvB;AAEA,SAAO,EAAE,WAAW,QAAA;AACtB;AAiBO,SAAS,mBAAmB,cAAsD;AACvF,QAAM,WAAW,YAAY,YAAY;AACzC,QAAM,iBAAiB,YAAY,uBAAuB;AAE1D,MAAI,aAAa,yBAAyB,UAAU;AAClD,UAAM,WAAW,aAAa,IAAI,mBAAmB,OAAO,QAAQ;AACpE,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,SACE,mCAAmC,aAAa,sBAAsB,6BAC3C,QAAQ;AAAA,IAAA;AAAA,EAEzC;AAEA,MAAI,iBAAiB,KAAK,aAAa,cAAc,gBAAgB;AACnE,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,SACE,sBAAsB,aAAa,WAAW,sDACrB,cAAc;AAAA,IAAA;AAAA,EAE7C;AAEA,SAAO,EAAE,IAAI,MAAM,QAAQ,KAAA;AAC7B;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kosdev-code/kos-api-levels",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.cjs",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"kos": {
|
|
24
24
|
"build": {
|
|
25
|
-
"gitHash": "
|
|
25
|
+
"gitHash": "681d3ed1315f7d905a8749f448fcc230639ed4a5"
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
}
|
package/registry.d.ts
CHANGED
package/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../packages/kos-api-levels/src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI3C;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAE3D;AAED,wBAAgB,WAAW,IAAI,QAAQ,CAAC,WAAW,CAAC,CAEnD"}
|
package/runtime.d.ts
CHANGED
package/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../packages/kos-api-levels/src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG3G;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ1E;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,QAAQ,CAAC,WAAW,CAAC,CAEvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAa9E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,wBAAwB,GAAG,YAAY,CA0BvF"}
|
package/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../packages/kos-api-levels/src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC5E;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|