signalk-container-helper 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/LICENSE +201 -0
- package/README.md +288 -0
- package/SPEC.md +309 -0
- package/dist/adopted-container.d.ts +55 -0
- package/dist/adopted-container.d.ts.map +1 -0
- package/dist/adopted-container.js +76 -0
- package/dist/adopted-container.js.map +1 -0
- package/dist/http.d.ts +66 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +76 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/managed-container.d.ts +203 -0
- package/dist/managed-container.d.ts.map +1 -0
- package/dist/managed-container.js +397 -0
- package/dist/managed-container.js.map +1 -0
- package/dist/manager.d.ts +44 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +50 -0
- package/dist/manager.js.map +1 -0
- package/dist/types.d.ts +493 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +20 -0
- package/dist/types.js.map +1 -0
- package/dist/util.d.ts +36 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +56 -0
- package/dist/util.js.map +1 -0
- package/dist/version-source.d.ts +23 -0
- package/dist/version-source.d.ts.map +1 -0
- package/dist/version-source.js +12 -0
- package/dist/version-source.js.map +1 -0
- package/package.json +57 -0
package/dist/util.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AppLike } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Allowed characters for an image tag before it is passed anywhere near the
|
|
4
|
+
* container runtime. Same guard as the reference plugins (SAFE_TAG).
|
|
5
|
+
*/
|
|
6
|
+
export declare const IMAGE_TAG_PATTERN: RegExp;
|
|
7
|
+
export declare function isValidImageTag(tag: unknown): tag is string;
|
|
8
|
+
/** Normalize an unknown thrown value into a printable message. */
|
|
9
|
+
export declare function errMsg(err: unknown): string;
|
|
10
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
11
|
+
export type ContainerHelperErrorCode = "manager-unavailable" | "no-runtime" | "invalid-tag" | "address-unresolved" | "not-ready" | "recreate-limbo";
|
|
12
|
+
/**
|
|
13
|
+
* Typed error thrown by ManagedContainer/AdoptedContainer operations.
|
|
14
|
+
* `reported` is true when the helper already surfaced the message via
|
|
15
|
+
* `app.setPluginError` — `startSafely` uses it to avoid double-reporting.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ContainerHelperError extends Error {
|
|
18
|
+
readonly code: ContainerHelperErrorCode;
|
|
19
|
+
reported: boolean;
|
|
20
|
+
constructor(code: ContainerHelperErrorCode, message: string, reported?: boolean);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Signal K calls `plugin.start()` synchronously and ignores a returned
|
|
24
|
+
* promise — an async `start` that rejects becomes an unhandled rejection with
|
|
25
|
+
* no plugin error surfaced. Wrap the async body with this from a synchronous
|
|
26
|
+
* `start()`:
|
|
27
|
+
*
|
|
28
|
+
* start(config) {
|
|
29
|
+
* startSafely(app, () => asyncStart(config))
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* Errors already reported by the helpers (ContainerHelperError.reported) are
|
|
33
|
+
* not re-reported; everything else lands in `setPluginError`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function startSafely(app: AppLike, fn: () => Promise<unknown>): void;
|
|
36
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AAErD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAO3D;AAED,kEAAkE;AAClE,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAE3C;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,MAAM,MAAM,wBAAwB,GAChC,qBAAqB,GACrB,YAAY,GACZ,aAAa,GACb,oBAAoB,GACpB,WAAW,GACX,gBAAgB,CAAC;AAErB;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,EAAE,OAAO,CAAC;gBAGhB,IAAI,EAAE,wBAAwB,EAC9B,OAAO,EAAE,MAAM,EACf,QAAQ,UAAQ;CAOnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAQ1E"}
|
package/dist/util.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Allowed characters for an image tag before it is passed anywhere near the
|
|
3
|
+
* container runtime. Same guard as the reference plugins (SAFE_TAG).
|
|
4
|
+
*/
|
|
5
|
+
export const IMAGE_TAG_PATTERN = /^[a-zA-Z0-9._-]+$/;
|
|
6
|
+
export function isValidImageTag(tag) {
|
|
7
|
+
return (typeof tag === "string" &&
|
|
8
|
+
tag.length > 0 &&
|
|
9
|
+
tag.length <= 128 &&
|
|
10
|
+
IMAGE_TAG_PATTERN.test(tag));
|
|
11
|
+
}
|
|
12
|
+
/** Normalize an unknown thrown value into a printable message. */
|
|
13
|
+
export function errMsg(err) {
|
|
14
|
+
return err instanceof Error ? err.message : String(err);
|
|
15
|
+
}
|
|
16
|
+
export function sleep(ms) {
|
|
17
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Typed error thrown by ManagedContainer/AdoptedContainer operations.
|
|
21
|
+
* `reported` is true when the helper already surfaced the message via
|
|
22
|
+
* `app.setPluginError` — `startSafely` uses it to avoid double-reporting.
|
|
23
|
+
*/
|
|
24
|
+
export class ContainerHelperError extends Error {
|
|
25
|
+
code;
|
|
26
|
+
reported;
|
|
27
|
+
constructor(code, message, reported = false) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = "ContainerHelperError";
|
|
30
|
+
this.code = code;
|
|
31
|
+
this.reported = reported;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Signal K calls `plugin.start()` synchronously and ignores a returned
|
|
36
|
+
* promise — an async `start` that rejects becomes an unhandled rejection with
|
|
37
|
+
* no plugin error surfaced. Wrap the async body with this from a synchronous
|
|
38
|
+
* `start()`:
|
|
39
|
+
*
|
|
40
|
+
* start(config) {
|
|
41
|
+
* startSafely(app, () => asyncStart(config))
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* Errors already reported by the helpers (ContainerHelperError.reported) are
|
|
45
|
+
* not re-reported; everything else lands in `setPluginError`.
|
|
46
|
+
*/
|
|
47
|
+
export function startSafely(app, fn) {
|
|
48
|
+
fn().catch((err) => {
|
|
49
|
+
if (err instanceof ContainerHelperError && err.reported) {
|
|
50
|
+
app.debug(`startup aborted: ${err.message}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
app.setPluginError(`Startup failed: ${errMsg(err)}`);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAErD,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,CAAC,MAAM,GAAG,CAAC;QACd,GAAG,CAAC,MAAM,IAAI,GAAG;QACjB,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAC5B,CAAC;AACJ,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,MAAM,CAAC,GAAY;IACjC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAUD;;;;GAIG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,IAAI,CAA2B;IACxC,QAAQ,CAAU;IAElB,YACE,IAA8B,EAC9B,OAAe,EACf,QAAQ,GAAG,KAAK;QAEhB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,EAA0B;IAClE,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QAC1B,IAAI,GAAG,YAAY,oBAAoB,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACxD,GAAG,CAAC,KAAK,CAAC,oBAAoB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QACD,GAAG,CAAC,cAAc,CAAC,mBAAmB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { UpdateServiceApi, VersionSource } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Declarative version-source description, resolved against
|
|
4
|
+
* `manager.updates.sources` at registration time so callers don't need the
|
|
5
|
+
* manager in hand while declaring their options.
|
|
6
|
+
*/
|
|
7
|
+
export type VersionSourceSpec = {
|
|
8
|
+
/** GitHub repo, e.g. "questdb/questdb". */
|
|
9
|
+
githubReleases: string;
|
|
10
|
+
allowPrerelease?: boolean;
|
|
11
|
+
tagPrefix?: string;
|
|
12
|
+
/** Personal access token — lifts the 60/hr anonymous rate limit. */
|
|
13
|
+
token?: string;
|
|
14
|
+
} | {
|
|
15
|
+
/** Docker Hub image, e.g. "questdb/questdb". */
|
|
16
|
+
dockerHubTags: string;
|
|
17
|
+
filter?: (tag: string) => boolean;
|
|
18
|
+
} | {
|
|
19
|
+
/** Bring your own VersionSource implementation. */
|
|
20
|
+
custom: VersionSource;
|
|
21
|
+
};
|
|
22
|
+
export declare function buildVersionSource(updates: UpdateServiceApi, spec: VersionSourceSpec): VersionSource;
|
|
23
|
+
//# sourceMappingURL=version-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-source.d.ts","sourceRoot":"","sources":["../src/version-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAElE;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GACzB;IACE,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACD;IACE,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACnC,GACD;IACE,mDAAmD;IACnD,MAAM,EAAE,aAAa,CAAC;CACvB,CAAC;AAEN,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,iBAAiB,GACtB,aAAa,CAUf"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function buildVersionSource(updates, spec) {
|
|
2
|
+
if ("custom" in spec) {
|
|
3
|
+
return spec.custom;
|
|
4
|
+
}
|
|
5
|
+
if ("githubReleases" in spec) {
|
|
6
|
+
const { githubReleases, ...options } = spec;
|
|
7
|
+
return updates.sources.githubReleases(githubReleases, options);
|
|
8
|
+
}
|
|
9
|
+
const { dockerHubTags, ...options } = spec;
|
|
10
|
+
return updates.sources.dockerHubTags(dockerHubTags, options);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=version-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-source.js","sourceRoot":"","sources":["../src/version-source.ts"],"names":[],"mappings":"AA0BA,MAAM,UAAU,kBAAkB,CAChC,OAAyB,EACzB,IAAuB;IAEvB,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IACD,IAAI,gBAAgB,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;QAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3C,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAC/D,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "signalk-container-helper",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Helper library for Signal K plugins that manage containers via the signalk-container plugin",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md",
|
|
17
|
+
"SPEC.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"test": "npm run typecheck:test && vitest run",
|
|
23
|
+
"test:watch": "vitest",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"typecheck:test": "tsc --noEmit --project tsconfig.test.json",
|
|
26
|
+
"prettier": "prettier --write .",
|
|
27
|
+
"lint": "eslint --fix",
|
|
28
|
+
"format": "npm run prettier && npm run lint",
|
|
29
|
+
"ci-lint": "eslint && prettier --check .",
|
|
30
|
+
"prepublishOnly": "npm run build && npm test"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"signalk",
|
|
34
|
+
"signalk-container",
|
|
35
|
+
"signalk-plugin",
|
|
36
|
+
"docker",
|
|
37
|
+
"podman",
|
|
38
|
+
"container"
|
|
39
|
+
],
|
|
40
|
+
"author": "hoeken",
|
|
41
|
+
"license": "Apache-2.0",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=24"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@eslint/js": "^10.0.1",
|
|
47
|
+
"@types/node": "^24.0.0",
|
|
48
|
+
"eslint": "^10.2.0",
|
|
49
|
+
"eslint-config-prettier": "^10.1.8",
|
|
50
|
+
"globals": "^17.4.0",
|
|
51
|
+
"prettier": "^3.8.1",
|
|
52
|
+
"signalk-container": "^1.23.2",
|
|
53
|
+
"typescript": "^5.5.0",
|
|
54
|
+
"typescript-eslint": "^8.58.0",
|
|
55
|
+
"vitest": "^3.0.0"
|
|
56
|
+
}
|
|
57
|
+
}
|