@aidc-toolkit/core 1.0.32-beta → 1.0.34-beta
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 +99 -92
- package/dist/app-data-storage.d.ts +118 -0
- package/dist/app-data-storage.d.ts.map +1 -0
- package/dist/app-data-storage.js +117 -0
- package/dist/app-data-storage.js.map +1 -0
- package/dist/app-data.d.ts +26 -0
- package/dist/app-data.d.ts.map +1 -0
- package/dist/app-data.js +79 -0
- package/dist/app-data.js.map +1 -0
- package/dist/browser-app-data-storage.d.ts +26 -0
- package/dist/browser-app-data-storage.d.ts.map +1 -0
- package/dist/browser-app-data-storage.js +34 -0
- package/dist/browser-app-data-storage.js.map +1 -0
- package/dist/file-app-data-storage.d.ts +26 -0
- package/dist/file-app-data-storage.d.ts.map +1 -0
- package/dist/file-app-data-storage.js +40 -0
- package/dist/file-app-data-storage.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/local-app-data-storage.d.ts +8 -0
- package/dist/local-app-data-storage.d.ts.map +1 -0
- package/dist/local-app-data-storage.js +11 -0
- package/dist/local-app-data-storage.js.map +1 -0
- package/dist/locale/en/locale-resources.d.ts +3 -0
- package/dist/locale/en/locale-resources.d.ts.map +1 -1
- package/dist/locale/en/locale-resources.js +3 -0
- package/dist/locale/en/locale-resources.js.map +1 -1
- package/dist/locale/fr/locale-resources.d.ts +3 -0
- package/dist/locale/fr/locale-resources.d.ts.map +1 -1
- package/dist/locale/fr/locale-resources.js +3 -0
- package/dist/locale/fr/locale-resources.js.map +1 -1
- package/dist/locale/i18n.d.ts +22 -13
- package/dist/locale/i18n.d.ts.map +1 -1
- package/dist/locale/i18n.js +62 -43
- package/dist/locale/i18n.js.map +1 -1
- package/dist/logger.d.ts +4 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +9 -3
- package/dist/logger.js.map +1 -1
- package/dist/parse-version.d.ts +36 -0
- package/dist/parse-version.d.ts.map +1 -0
- package/dist/parse-version.js +23 -0
- package/dist/parse-version.js.map +1 -0
- package/dist/phase-url.d.ts +17 -0
- package/dist/phase-url.d.ts.map +1 -0
- package/dist/phase-url.js +39 -0
- package/dist/phase-url.js.map +1 -0
- package/dist/remote-app-data-storage.d.ts +18 -0
- package/dist/remote-app-data-storage.d.ts.map +1 -0
- package/dist/remote-app-data-storage.js +37 -0
- package/dist/remote-app-data-storage.js.map +1 -0
- package/dist/type-helper.js.map +1 -1
- package/package.json +11 -8
- package/src/app-data-storage.ts +166 -0
- package/src/app-data.ts +94 -0
- package/src/browser-app-data-storage.ts +37 -0
- package/src/file-app-data-storage.ts +49 -0
- package/src/index.ts +10 -1
- package/src/local-app-data-storage.ts +12 -0
- package/src/locale/en/locale-resources.ts +3 -0
- package/src/locale/fr/locale-resources.ts +3 -0
- package/src/locale/i18n.ts +81 -49
- package/src/logger.ts +10 -3
- package/src/parse-version.ts +54 -0
- package/src/phase-url.ts +42 -0
- package/src/remote-app-data-storage.ts +38 -0
- package/src/type-helper.ts +2 -2
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse version.
|
|
3
|
+
*
|
|
4
|
+
* @param version
|
|
5
|
+
* Version, typically from package.json.
|
|
6
|
+
*
|
|
7
|
+
* @returns
|
|
8
|
+
* Parsed version.
|
|
9
|
+
*/
|
|
10
|
+
export function parseVersion(version) {
|
|
11
|
+
const parsedVersionGroups = /^(?<majorVersion>\d+)\.(?<minorVersion>\d+)\.(?<patchVersion>\d+)(?:-(?<preReleaseIdentifier>alpha|beta)(?:\.(?<dateTime>\d{12}))?)?$/u.exec(version)?.groups;
|
|
12
|
+
if (parsedVersionGroups === undefined) {
|
|
13
|
+
throw new Error(`Invalid package version ${version}`);
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
majorVersion: Number(parsedVersionGroups["majorVersion"]),
|
|
17
|
+
minorVersion: Number(parsedVersionGroups["minorVersion"]),
|
|
18
|
+
patchVersion: Number(parsedVersionGroups["patchVersion"]),
|
|
19
|
+
preReleaseIdentifier: parsedVersionGroups["preReleaseIdentifier"],
|
|
20
|
+
dateTime: parsedVersionGroups["dateTime"]
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=parse-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-version.js","sourceRoot":"","sources":["../src/parse-version.ts"],"names":[],"mappings":"AA8BA;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IACxC,MAAM,mBAAmB,GAAG,wIAAwI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAE3L,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO;QACH,YAAY,EAAE,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;QACzD,YAAY,EAAE,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;QACzD,YAAY,EAAE,MAAM,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;QACzD,oBAAoB,EAAE,mBAAmB,CAAC,sBAAsB,CAAC;QACjE,QAAQ,EAAE,mBAAmB,CAAC,UAAU,CAAC;KAC5C,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the URL for the phase as determined by the package version.
|
|
3
|
+
*
|
|
4
|
+
* @param version
|
|
5
|
+
* Package version.
|
|
6
|
+
*
|
|
7
|
+
* @param alphaURL
|
|
8
|
+
* Alpha URL.
|
|
9
|
+
*
|
|
10
|
+
* @param nonAlphaRelativeURL
|
|
11
|
+
* Non-alpha URL, relative to non-alpha base URL plus optionally the pre-release identifier and version.
|
|
12
|
+
*
|
|
13
|
+
* @returns
|
|
14
|
+
* Fully-formed URL for the phase.
|
|
15
|
+
*/
|
|
16
|
+
export declare function phaseURL(version: string, alphaURL: string, nonAlphaRelativeURL?: string): string;
|
|
17
|
+
//# sourceMappingURL=phase-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase-url.d.ts","sourceRoot":"","sources":["../src/phase-url.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,MAAM,CAsBhG"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { parseVersion } from "./parse-version.js";
|
|
2
|
+
const NON_ALPHA_BASE_URL = "https://aidc-toolkit.com";
|
|
3
|
+
/**
|
|
4
|
+
* Get the URL for the phase as determined by the package version.
|
|
5
|
+
*
|
|
6
|
+
* @param version
|
|
7
|
+
* Package version.
|
|
8
|
+
*
|
|
9
|
+
* @param alphaURL
|
|
10
|
+
* Alpha URL.
|
|
11
|
+
*
|
|
12
|
+
* @param nonAlphaRelativeURL
|
|
13
|
+
* Non-alpha URL, relative to non-alpha base URL plus optionally the pre-release identifier and version.
|
|
14
|
+
*
|
|
15
|
+
* @returns
|
|
16
|
+
* Fully-formed URL for the phase.
|
|
17
|
+
*/
|
|
18
|
+
export function phaseURL(version, alphaURL, nonAlphaRelativeURL) {
|
|
19
|
+
const parsedVersion = parseVersion(version);
|
|
20
|
+
const preReleaseIdentifier = parsedVersion.preReleaseIdentifier;
|
|
21
|
+
let url;
|
|
22
|
+
if (preReleaseIdentifier === "alpha") {
|
|
23
|
+
// Alpha URL is absolute.
|
|
24
|
+
url = alphaURL;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const relativeURL = nonAlphaRelativeURL !== undefined && nonAlphaRelativeURL !== "" ? `/${nonAlphaRelativeURL}` : "";
|
|
28
|
+
if (preReleaseIdentifier !== undefined) {
|
|
29
|
+
// Non-alpha URL is relative to non-alpha base URL plus pre-release identifier and version.
|
|
30
|
+
url = `${NON_ALPHA_BASE_URL}/${preReleaseIdentifier}/v${parsedVersion.majorVersion}.${parsedVersion.minorVersion}${relativeURL}`;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// Production URL is relative to non-alpha base URL.
|
|
34
|
+
url = `${NON_ALPHA_BASE_URL}${relativeURL}`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return url;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=phase-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase-url.js","sourceRoot":"","sources":["../src/phase-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAEtD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,QAAgB,EAAE,mBAA4B;IACpF,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,oBAAoB,GAAG,aAAa,CAAC,oBAAoB,CAAC;IAEhE,IAAI,GAAW,CAAC;IAEhB,IAAI,oBAAoB,KAAK,OAAO,EAAE,CAAC;QACnC,yBAAyB;QACzB,GAAG,GAAG,QAAQ,CAAC;IACnB,CAAC;SAAM,CAAC;QACJ,MAAM,WAAW,GAAG,mBAAmB,KAAK,SAAS,IAAI,mBAAmB,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAErH,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;YACrC,2FAA2F;YAC3F,GAAG,GAAG,GAAG,kBAAkB,IAAI,oBAAoB,KAAK,aAAa,CAAC,YAAY,IAAI,aAAa,CAAC,YAAY,GAAG,WAAW,EAAE,CAAC;QACrI,CAAC;aAAM,CAAC;YACJ,oDAAoD;YACpD,GAAG,GAAG,GAAG,kBAAkB,GAAG,WAAW,EAAE,CAAC;QAChD,CAAC;IACL,CAAC;IAED,OAAO,GAAG,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReadOnlyAppDataStorage } from "./app-data-storage.js";
|
|
2
|
+
/**
|
|
3
|
+
* Remote application data storage using HTTP. The `store()` and `delete()` methods are not supported.
|
|
4
|
+
*/
|
|
5
|
+
export declare class RemoteAppDataStorage extends ReadOnlyAppDataStorage<true> {
|
|
6
|
+
/**
|
|
7
|
+
* Constructor.
|
|
8
|
+
*
|
|
9
|
+
* @param baseURL
|
|
10
|
+
* Base URL. The URL must not end with a slash.
|
|
11
|
+
*/
|
|
12
|
+
constructor(baseURL: string);
|
|
13
|
+
/**
|
|
14
|
+
* @inheritDoc
|
|
15
|
+
*/
|
|
16
|
+
protected doRead(key: string, asBinary: boolean | undefined): Promise<string | Uint8Array | undefined>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=remote-app-data-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-app-data-storage.d.ts","sourceRoot":"","sources":["../src/remote-app-data-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAG/D;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,sBAAsB,CAAC,IAAI,CAAC;IAClE;;;;;OAKG;gBACS,OAAO,EAAE,MAAM;IAI3B;;OAEG;cACsB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;CAiBxH"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ReadOnlyAppDataStorage } from "./app-data-storage.js";
|
|
2
|
+
import { i18nextCore } from "./locale/i18n.js";
|
|
3
|
+
/**
|
|
4
|
+
* Remote application data storage using HTTP. The `store()` and `delete()` methods are not supported.
|
|
5
|
+
*/
|
|
6
|
+
export class RemoteAppDataStorage extends ReadOnlyAppDataStorage {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor.
|
|
9
|
+
*
|
|
10
|
+
* @param baseURL
|
|
11
|
+
* Base URL. The URL must not end with a slash.
|
|
12
|
+
*/
|
|
13
|
+
constructor(baseURL) {
|
|
14
|
+
super(true, baseURL);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* @inheritDoc
|
|
18
|
+
*/
|
|
19
|
+
async doRead(key, asBinary) {
|
|
20
|
+
return fetch(key).then(async (response) => {
|
|
21
|
+
let result;
|
|
22
|
+
if (response.ok) {
|
|
23
|
+
result = asBinary === true ? new Uint8Array(await response.arrayBuffer()) : await response.text();
|
|
24
|
+
}
|
|
25
|
+
else if (response.status === 404) {
|
|
26
|
+
result = undefined;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
throw new RangeError(i18nextCore.t("RemoteAppDataStorage.httpError", {
|
|
30
|
+
status: response.status
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=remote-app-data-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-app-data-storage.js","sourceRoot":"","sources":["../src/remote-app-data-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,sBAA4B;IAClE;;;;;OAKG;IACH,YAAY,OAAe;QACvB,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzB,CAAC;IAED;;OAEG;IACgB,KAAK,CAAC,MAAM,CAAC,GAAW,EAAE,QAA6B;QACtE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YACtC,IAAI,MAAuC,CAAC;YAE5C,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACd,MAAM,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACtG,CAAC;iBAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACjC,MAAM,GAAG,SAAS,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACJ,MAAM,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,gCAAgC,EAAE;oBACjE,MAAM,EAAE,QAAQ,CAAC,MAAM;iBAC1B,CAAC,CAAC,CAAC;YACR,CAAC;YAED,OAAO,MAAM,CAAC;QAClB,CAAC,CAAC,CAAC;IACP,CAAC;CACJ"}
|
package/dist/type-helper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-helper.js","sourceRoot":"","sources":["../src/type-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAS,UAAU,CAAgE,QAAkB,EAAE,CAAI,EAAE,GAAG,IAAS;IACrH,yGAAyG;IACzG,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAQ,CAAC,KAAK,QAAQ,CAAC,CAAkD,CAAC;AAC1J,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,IAAI,CAAsC,CAAI,EAAE,GAAG,IAAS;IACxE,OAAO,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,IAAI,CAAsC,CAAI,EAAE,GAAG,IAAS;IACxE,OAAO,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,OAAO,CAAyE,IAAW,EAAE,MAAe;IACxH,0FAA0F;IAC1F,OAAO,IAAI,CAAC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"type-helper.js","sourceRoot":"","sources":["../src/type-helper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAS,UAAU,CAAgE,QAAkB,EAAE,CAAI,EAAE,GAAG,IAAS;IACrH,yGAAyG;IACzG,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAQ,CAAC,KAAK,QAAQ,CAAC,CAAkD,CAAC;AAC1J,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,IAAI,CAAsC,CAAI,EAAE,GAAG,IAAS;IACxE,OAAO,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,IAAI,CAAsC,CAAI,EAAE,GAAG,IAAS;IACxE,OAAO,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,OAAO,CAAyE,IAAW,EAAE,MAAe;IACxH,0FAA0F;IAC1F,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAQ,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,OAAO,CAAyE,IAAW,EAAE,MAAe;IACxH,0FAA0F;IAC1F,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAQ,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,UAAU,CAA4D,CAAI,EAAE,GAAM;IAC9F,2GAA2G;IAC3G,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QACd;YACI,sFAAsF;YACtF,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAY;SAC3B,CAAC,CAAC;QACH,EAAE,CAC2C,CAAC;AACtD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,QAAiB;IACvC,OAAO,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,CAAC;AACvD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aidc-toolkit/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.34-beta",
|
|
4
4
|
"description": "Core functionality for AIDC Toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
|
-
"homepage": "https://aidc-toolkit.com
|
|
7
|
+
"homepage": "https://aidc-toolkit.com",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
10
|
"url": "git+https://github.com/aidc-toolkit/core.git"
|
|
@@ -20,16 +20,19 @@
|
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"lint": "eslint",
|
|
23
|
-
"tsc
|
|
24
|
-
"build:
|
|
25
|
-
"build:
|
|
26
|
-
"build:
|
|
23
|
+
"tsc-src": "tsc --project tsconfig-src.json",
|
|
24
|
+
"build:non-prod": "rimraf dist && npm run tsc-src -- --declarationMap --sourceMap",
|
|
25
|
+
"build:alpha": "npm run build:non-prod && tsc --project tsconfig-config.json --noEmit",
|
|
26
|
+
"build:beta": "npm run build:non-prod",
|
|
27
|
+
"build:prod": "npm run tsc-src -- --noEmit && tsup",
|
|
28
|
+
"build:doc": "npm run build:non-prod"
|
|
27
29
|
},
|
|
28
30
|
"devDependencies": {
|
|
29
|
-
"@aidc-toolkit/dev": "1.0.
|
|
31
|
+
"@aidc-toolkit/dev": "1.0.34-beta"
|
|
30
32
|
},
|
|
31
33
|
"dependencies": {
|
|
32
|
-
"
|
|
34
|
+
"base64-js": "^1.5.1",
|
|
35
|
+
"i18next": "^25.8.0",
|
|
33
36
|
"i18next-browser-languagedetector": "^8.2.0",
|
|
34
37
|
"i18next-cli-language-detector": "^1.1.8",
|
|
35
38
|
"tslog": "^4.10.2"
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { type AppData, decodeAppData, encodeAppData } from "./app-data.js";
|
|
2
|
+
import type { Promisable } from "./type.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generic read-only application data storage.
|
|
6
|
+
*/
|
|
7
|
+
export abstract class ReadOnlyAppDataStorage<SupportsBinary extends boolean> {
|
|
8
|
+
/**
|
|
9
|
+
* Extension to identify binary data.
|
|
10
|
+
*/
|
|
11
|
+
protected static readonly BINARY_EXTENSION = ".bin";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Extension to identify JSON data.
|
|
15
|
+
*/
|
|
16
|
+
protected static readonly JSON_EXTENSION = ".json";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* True if binary data is supported natively.
|
|
20
|
+
*/
|
|
21
|
+
readonly #supportsBinary: SupportsBinary;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Storage path prepended to each key.
|
|
25
|
+
*/
|
|
26
|
+
readonly #path: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Constructor.
|
|
30
|
+
*
|
|
31
|
+
* @param supportsBinary
|
|
32
|
+
* True if binary data is supported.
|
|
33
|
+
*
|
|
34
|
+
* @param path
|
|
35
|
+
* Storage path prepended to each key along with '/' if defined, empty string if not.
|
|
36
|
+
*/
|
|
37
|
+
protected constructor(supportsBinary: SupportsBinary, path?: string) {
|
|
38
|
+
this.#supportsBinary = supportsBinary;
|
|
39
|
+
this.#path = path !== undefined ? `${path}/` : "";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Determine if binary data is supported.
|
|
44
|
+
*/
|
|
45
|
+
get supportsBinary(): SupportsBinary {
|
|
46
|
+
return this.#supportsBinary;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get the storage path, prepended to each key.
|
|
51
|
+
*/
|
|
52
|
+
get path(): string {
|
|
53
|
+
return this.#path;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Build the full storage key.
|
|
58
|
+
*
|
|
59
|
+
* @param pathKey
|
|
60
|
+
* Key relative to path.
|
|
61
|
+
*
|
|
62
|
+
* @param isBinary
|
|
63
|
+
* True if key is to binary data, false or undefined if to string data. Ignored if binary data is not supported.
|
|
64
|
+
*
|
|
65
|
+
* @returns
|
|
66
|
+
* Full storage key.
|
|
67
|
+
*/
|
|
68
|
+
protected fullKey(pathKey: string, isBinary: boolean): string {
|
|
69
|
+
const keyNoExtension = `${this.path}${pathKey}`;
|
|
70
|
+
|
|
71
|
+
// Add extension to key if binary data is supported.
|
|
72
|
+
return this.supportsBinary ?
|
|
73
|
+
`${keyNoExtension}${isBinary ? ReadOnlyAppDataStorage.BINARY_EXTENSION : ReadOnlyAppDataStorage.JSON_EXTENSION}` :
|
|
74
|
+
keyNoExtension;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Read a string or binary data from persistent storage.
|
|
79
|
+
*
|
|
80
|
+
* @param key
|
|
81
|
+
* Storage key (file path in Node.js, key in localStorage).
|
|
82
|
+
*
|
|
83
|
+
* @param asBinary
|
|
84
|
+
* True if binary data is requested, false or undefined if string data is requested. Ignored if binary data is not
|
|
85
|
+
* supported.
|
|
86
|
+
*
|
|
87
|
+
* @returns
|
|
88
|
+
* String or binary data or undefined if not found.
|
|
89
|
+
*/
|
|
90
|
+
protected abstract doRead(key: string, asBinary: boolean | undefined): Promisable<(SupportsBinary extends true ? string | Uint8Array : string) | undefined>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Read application data from storage.
|
|
94
|
+
*
|
|
95
|
+
* @param pathKey
|
|
96
|
+
* Key relative to path.
|
|
97
|
+
*
|
|
98
|
+
* @param asBinary
|
|
99
|
+
* True if binary data is requested, false or undefined if string data is requested. Ignored if binary data is not
|
|
100
|
+
* supported.
|
|
101
|
+
*
|
|
102
|
+
* @returns
|
|
103
|
+
* Application data or undefined if not found.
|
|
104
|
+
*/
|
|
105
|
+
async read(pathKey: string, asBinary?: boolean): Promise<AppData | undefined> {
|
|
106
|
+
const data = await this.doRead(this.fullKey(pathKey, asBinary === true), asBinary);
|
|
107
|
+
|
|
108
|
+
return typeof data === "string" ? decodeAppData(data) : data;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Generic read/write application data storage.
|
|
114
|
+
*/
|
|
115
|
+
export abstract class AppDataStorage<SupportsBinary extends boolean> extends ReadOnlyAppDataStorage<SupportsBinary> {
|
|
116
|
+
/**
|
|
117
|
+
* Write a string or binary data in persistent storage.
|
|
118
|
+
*
|
|
119
|
+
* @param key
|
|
120
|
+
* Storage key (file path in Node.js, key in localStorage).
|
|
121
|
+
*
|
|
122
|
+
* @param data
|
|
123
|
+
* String or binary data.
|
|
124
|
+
*/
|
|
125
|
+
protected abstract doWrite(key: string, data: SupportsBinary extends true ? string | Uint8Array : string): Promisable<void>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Write application data to storage.
|
|
129
|
+
*
|
|
130
|
+
* @param pathKey
|
|
131
|
+
* Key relative to path.
|
|
132
|
+
*
|
|
133
|
+
* @param appData
|
|
134
|
+
* Application data to write.
|
|
135
|
+
*/
|
|
136
|
+
async write(pathKey: string, appData: AppData): Promise<void> {
|
|
137
|
+
const isBinary = appData instanceof Uint8Array;
|
|
138
|
+
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Type is determined by supports binary flag.
|
|
140
|
+
await this.doWrite(this.fullKey(pathKey, isBinary), (this.supportsBinary && isBinary ?
|
|
141
|
+
appData :
|
|
142
|
+
encodeAppData(appData)
|
|
143
|
+
) as Parameters<typeof this.doWrite>[1]);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Delete from persistent storage.
|
|
148
|
+
*
|
|
149
|
+
* @param key
|
|
150
|
+
* Storage key (file path in Node.js, key in localStorage).
|
|
151
|
+
*/
|
|
152
|
+
protected abstract doDelete(key: string): Promisable<void>;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Delete application data from persistent storage.
|
|
156
|
+
*
|
|
157
|
+
* @param pathKey
|
|
158
|
+
* Key relative to path.
|
|
159
|
+
*
|
|
160
|
+
* @param asBinary
|
|
161
|
+
* True if key is to binary data, false or undefined if to string data. Ignored if binary data is not supported.
|
|
162
|
+
*/
|
|
163
|
+
async delete(pathKey: string, asBinary?: boolean): Promise<void> {
|
|
164
|
+
await this.doDelete(this.fullKey(pathKey, asBinary === true));
|
|
165
|
+
}
|
|
166
|
+
}
|
package/src/app-data.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { fromByteArray, toByteArray } from "base64-js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Application data.
|
|
5
|
+
*/
|
|
6
|
+
export type AppData = string | number | boolean | object;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Decode application data from an encoded string.
|
|
10
|
+
*
|
|
11
|
+
* @param stringData
|
|
12
|
+
* String data.
|
|
13
|
+
*
|
|
14
|
+
* @returns
|
|
15
|
+
* Decoded application data.
|
|
16
|
+
*/
|
|
17
|
+
export function decodeAppData(stringData: string): AppData | undefined {
|
|
18
|
+
let decodedAppData: AppData | undefined;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Mapping is expected to be correct.
|
|
22
|
+
decodedAppData = JSON.parse(stringData, (_key, value: unknown) => {
|
|
23
|
+
let replacementValue = value;
|
|
24
|
+
|
|
25
|
+
// Decode string representing date/time and binary array and pass through other values unmodified.
|
|
26
|
+
if (typeof value === "string") {
|
|
27
|
+
// First capture group is type, second is data; simple split at ':' character.
|
|
28
|
+
const stringDataGroups = /^(?<type>\w+):(?<data>.*)$/u.exec(value)?.groups;
|
|
29
|
+
|
|
30
|
+
if (stringDataGroups !== undefined) {
|
|
31
|
+
const type = stringDataGroups["type"];
|
|
32
|
+
const data = stringDataGroups["data"];
|
|
33
|
+
|
|
34
|
+
switch (type) {
|
|
35
|
+
case "dateTime":
|
|
36
|
+
replacementValue = new Date(data);
|
|
37
|
+
break;
|
|
38
|
+
|
|
39
|
+
case "binary":
|
|
40
|
+
replacementValue = toByteArray(data);
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return replacementValue;
|
|
47
|
+
}) as AppData;
|
|
48
|
+
} catch {
|
|
49
|
+
// String data is not valid JSON; discard it.
|
|
50
|
+
decodedAppData = undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return decodedAppData;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Encode an object to a format suitable for storage.
|
|
58
|
+
*
|
|
59
|
+
* @param o
|
|
60
|
+
* Object.
|
|
61
|
+
*
|
|
62
|
+
* @returns
|
|
63
|
+
* Object suitable for storage with date/time and binary types encoded as strings.
|
|
64
|
+
*/
|
|
65
|
+
function encodeObject(o: object): object | string {
|
|
66
|
+
let mappedData: object | string;
|
|
67
|
+
|
|
68
|
+
// Encode date/time and binary array as string and pass through other values unmodified.
|
|
69
|
+
if (o instanceof Date) {
|
|
70
|
+
mappedData = `dateTime:${o.toISOString()}`;
|
|
71
|
+
} else if (o instanceof Uint8Array) {
|
|
72
|
+
mappedData = `binary:${fromByteArray(o)}`;
|
|
73
|
+
} else {
|
|
74
|
+
mappedData = Object.fromEntries(Object.entries(o).map(([key, value]: [string, unknown]) =>
|
|
75
|
+
[key, typeof value === "object" && value !== null ? encodeObject(value) : value]
|
|
76
|
+
));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return mappedData;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Encode application data as a string for storage. Encoded string is in JSON format with date/time and binary data
|
|
84
|
+
* converted to identifiable strings for decoding.
|
|
85
|
+
*
|
|
86
|
+
* @param appData
|
|
87
|
+
* Application data.
|
|
88
|
+
*
|
|
89
|
+
* @returns
|
|
90
|
+
* Encoded application data.
|
|
91
|
+
*/
|
|
92
|
+
export function encodeAppData(appData: AppData): string {
|
|
93
|
+
return JSON.stringify(typeof appData !== "object" ? appData : encodeObject(appData));
|
|
94
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { AppDataStorage } from "./app-data-storage.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Application data storage using the browser local storage.
|
|
5
|
+
*/
|
|
6
|
+
export class BrowserAppDataStorage extends AppDataStorage<false> {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor.
|
|
9
|
+
*
|
|
10
|
+
* @param path
|
|
11
|
+
* Storage path prepended to each key along with '/' if defined, empty string if not.
|
|
12
|
+
*/
|
|
13
|
+
constructor(path?: string) {
|
|
14
|
+
super(false, path);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @inheritDoc
|
|
19
|
+
*/
|
|
20
|
+
protected override doRead(key: string): string | undefined {
|
|
21
|
+
return localStorage.getItem(key) ?? undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @inheritDoc
|
|
26
|
+
*/
|
|
27
|
+
protected override doWrite(key: string, s: string): void {
|
|
28
|
+
localStorage.setItem(key, s);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @inheritDoc
|
|
33
|
+
*/
|
|
34
|
+
protected override doDelete(key: string): void {
|
|
35
|
+
localStorage.removeItem(key);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { AppDataStorage } from "./app-data-storage.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Application data storage using the file system.
|
|
7
|
+
*/
|
|
8
|
+
export class FileAppDataStorage extends AppDataStorage<true> {
|
|
9
|
+
/**
|
|
10
|
+
* Constructor.
|
|
11
|
+
*
|
|
12
|
+
* @param path
|
|
13
|
+
* Storage path prepended to each key along with '/' if defined, empty string if not.
|
|
14
|
+
*/
|
|
15
|
+
constructor(path?: string) {
|
|
16
|
+
super(true, path);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @inheritDoc
|
|
21
|
+
*/
|
|
22
|
+
protected override async doRead(key: string, asBinary: boolean | undefined): Promise<string | Uint8Array | undefined> {
|
|
23
|
+
return fs.promises.readFile(key).then(buffer =>
|
|
24
|
+
asBinary === true ? buffer : buffer.toString()
|
|
25
|
+
).catch(() =>
|
|
26
|
+
undefined
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @inheritDoc
|
|
32
|
+
*/
|
|
33
|
+
protected override async doWrite(key: string, data: string | Uint8Array): Promise<void> {
|
|
34
|
+
return fs.promises.mkdir(path.dirname(key), {
|
|
35
|
+
recursive: true
|
|
36
|
+
}).then(async () =>
|
|
37
|
+
fs.promises.writeFile(key, data)
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @inheritDoc
|
|
43
|
+
*/
|
|
44
|
+
protected override async doDelete(key: string): Promise<void> {
|
|
45
|
+
return fs.promises.rm(key, {
|
|
46
|
+
force: true
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Copyright © 2024-
|
|
2
|
+
* Copyright © 2024-2026 Dolphin Data Development Ltd. and AIDC Toolkit
|
|
3
3
|
* contributors
|
|
4
4
|
*
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -14,12 +14,21 @@
|
|
|
14
14
|
* See the License for the specific language governing permissions and
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
|
+
|
|
17
18
|
export type * from "./type.js";
|
|
18
19
|
export * from "./type-helper.js";
|
|
19
20
|
|
|
20
21
|
export * from "./logger.js";
|
|
21
22
|
|
|
23
|
+
export * from "./parse-version.js";
|
|
24
|
+
export * from "./phase-url.js";
|
|
25
|
+
|
|
26
|
+
export * from "./app-data.js";
|
|
27
|
+
export * from "./app-data-storage.js";
|
|
28
|
+
export * from "./local-app-data-storage.js";
|
|
29
|
+
export * from "./remote-app-data-storage.js";
|
|
22
30
|
export * from "./cache.js";
|
|
31
|
+
|
|
23
32
|
export type * from "./hyperlink.js";
|
|
24
33
|
|
|
25
34
|
export * from "./locale/i18n.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AppDataStorage } from "./app-data-storage.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Local application data storage class for the current environment. This is a variable representing a `Promise` as the
|
|
5
|
+
* implementing class is loaded dynamically to prevent the inclusion of unnecessary node dependencies in a browser
|
|
6
|
+
* environment.
|
|
7
|
+
*/
|
|
8
|
+
export const LocalAppDataStorage: Promise<new (path?: string) => AppDataStorage<boolean>> =
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- localStorage is undefined when running under Node.js.
|
|
10
|
+
globalThis.localStorage === undefined ?
|
|
11
|
+
import("./file-app-data-storage.js").then(module => module.FileAppDataStorage) :
|
|
12
|
+
import("./browser-app-data-storage.js").then(module => module.BrowserAppDataStorage);
|