ega-v9 1.0.0 → 1.0.2
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/dist/cli/commercial-api-client.d.ts +26 -0
- package/dist/cli/commercial-api-client.js +90 -0
- package/dist/cli/ega-v9.d.ts +2 -0
- package/dist/cli/ega-v9.js +76 -0
- package/dist/cli/license-api-client.d.ts +20 -0
- package/dist/cli/license-api-client.js +139 -0
- package/dist/cli/register-command.d.ts +28 -0
- package/dist/cli/register-command.js +104 -0
- package/dist/cli/upgrade-command.d.ts +5 -0
- package/dist/cli/upgrade-command.js +90 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +170 -1
- package/dist/index.mjs +27 -0
- package/dist/license/evaluate-license.d.ts +2 -0
- package/dist/license/evaluate-license.js +89 -0
- package/dist/license/license-key.d.ts +32 -0
- package/dist/license/license-key.js +286 -0
- package/dist/license/license-store.d.ts +37 -0
- package/dist/license/license-store.js +181 -0
- package/dist/license/public-key.d.ts +5 -0
- package/dist/license/public-key.js +29 -0
- package/dist/license/runtime-admission-provider.d.ts +9 -0
- package/dist/license/runtime-admission-provider.js +30 -0
- package/dist/license/runtime-admission.d.ts +30 -0
- package/dist/license/runtime-admission.js +170 -0
- package/dist/license/types.d.ts +32 -0
- package/dist/license/types.js +2 -0
- package/dist/license/usage-reporter.d.ts +27 -0
- package/dist/license/usage-reporter.js +119 -0
- package/package.json +17 -4
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type EGACommercialUpgradeStatus = "pending" | "approved" | "rejected";
|
|
2
|
+
export type EGACommercialRequestResult = {
|
|
3
|
+
created: boolean;
|
|
4
|
+
requestId: string;
|
|
5
|
+
status: EGACommercialUpgradeStatus;
|
|
6
|
+
};
|
|
7
|
+
export type EGACommercialStatusResult = {
|
|
8
|
+
requested: boolean;
|
|
9
|
+
requestId: string | null;
|
|
10
|
+
status: EGACommercialUpgradeStatus | null;
|
|
11
|
+
rejectionReason?: string | null;
|
|
12
|
+
commercialLicenseKey?: string | null;
|
|
13
|
+
};
|
|
14
|
+
export type EGACommercialApiClientOptions = {
|
|
15
|
+
apiBaseUrl: string;
|
|
16
|
+
fetchImplementation?: typeof fetch;
|
|
17
|
+
timeoutMilliseconds?: number;
|
|
18
|
+
};
|
|
19
|
+
export declare class EGACommercialApiError extends Error {
|
|
20
|
+
readonly code: "EGA_COMMERCIAL_API_CONFIG" | "EGA_COMMERCIAL_API_NETWORK" | "EGA_COMMERCIAL_API_RESPONSE";
|
|
21
|
+
constructor(code: EGACommercialApiError["code"], message: string);
|
|
22
|
+
}
|
|
23
|
+
export declare function createCommercialApiClient(options: EGACommercialApiClientOptions): {
|
|
24
|
+
requestUpgrade(licenseKey: string): Promise<EGACommercialRequestResult>;
|
|
25
|
+
getStatus(licenseKey: string): Promise<EGACommercialStatusResult>;
|
|
26
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EGACommercialApiError = void 0;
|
|
4
|
+
exports.createCommercialApiClient = createCommercialApiClient;
|
|
5
|
+
class EGACommercialApiError extends Error {
|
|
6
|
+
constructor(code, message) {
|
|
7
|
+
super(`[${code}] ${message}`);
|
|
8
|
+
this.name =
|
|
9
|
+
"EGACommercialApiError";
|
|
10
|
+
this.code =
|
|
11
|
+
code;
|
|
12
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.EGACommercialApiError = EGACommercialApiError;
|
|
16
|
+
function normalizeBaseUrl(value) {
|
|
17
|
+
let url;
|
|
18
|
+
try {
|
|
19
|
+
url =
|
|
20
|
+
new URL(value.trim());
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw new EGACommercialApiError("EGA_COMMERCIAL_API_CONFIG", "Commercial License API URL is invalid.");
|
|
24
|
+
}
|
|
25
|
+
if (url.protocol !== "https:" &&
|
|
26
|
+
!(url.protocol === "http:" &&
|
|
27
|
+
(url.hostname ===
|
|
28
|
+
"127.0.0.1" ||
|
|
29
|
+
url.hostname ===
|
|
30
|
+
"localhost"))) {
|
|
31
|
+
throw new EGACommercialApiError("EGA_COMMERCIAL_API_CONFIG", "Commercial License API must use HTTPS except for localhost development.");
|
|
32
|
+
}
|
|
33
|
+
return url
|
|
34
|
+
.toString()
|
|
35
|
+
.replace(/\/$/, "");
|
|
36
|
+
}
|
|
37
|
+
function createCommercialApiClient(options) {
|
|
38
|
+
const baseUrl = normalizeBaseUrl(options.apiBaseUrl);
|
|
39
|
+
const fetchImplementation = options.fetchImplementation ??
|
|
40
|
+
fetch;
|
|
41
|
+
const timeoutMilliseconds = options.timeoutMilliseconds ??
|
|
42
|
+
10000;
|
|
43
|
+
async function request(path, method, licenseKey) {
|
|
44
|
+
const controller = new AbortController();
|
|
45
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMilliseconds);
|
|
46
|
+
try {
|
|
47
|
+
let response;
|
|
48
|
+
try {
|
|
49
|
+
response =
|
|
50
|
+
await fetchImplementation(`${baseUrl}${path}`, {
|
|
51
|
+
method,
|
|
52
|
+
headers: {
|
|
53
|
+
accept: "application/json",
|
|
54
|
+
authorization: `Bearer ${licenseKey}`
|
|
55
|
+
},
|
|
56
|
+
signal: controller.signal
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new EGACommercialApiError("EGA_COMMERCIAL_API_NETWORK", error instanceof Error
|
|
61
|
+
? error.message
|
|
62
|
+
: "Unable to contact the Commercial License API.");
|
|
63
|
+
}
|
|
64
|
+
let body;
|
|
65
|
+
try {
|
|
66
|
+
body =
|
|
67
|
+
await response.json();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new EGACommercialApiError("EGA_COMMERCIAL_API_RESPONSE", "Commercial License API returned invalid JSON.");
|
|
71
|
+
}
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
throw new EGACommercialApiError("EGA_COMMERCIAL_API_RESPONSE", body?.error?.message ??
|
|
74
|
+
"Commercial License API rejected the request.");
|
|
75
|
+
}
|
|
76
|
+
return body;
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
clearTimeout(timeout);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
async requestUpgrade(licenseKey) {
|
|
84
|
+
return await request("/api/licenses/commercial/request", "POST", licenseKey);
|
|
85
|
+
},
|
|
86
|
+
async getStatus(licenseKey) {
|
|
87
|
+
return await request("/api/licenses/commercial/status", "GET", licenseKey);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const promises_1 = require("readline/promises");
|
|
5
|
+
const process_1 = require("process");
|
|
6
|
+
const register_command_1 = require("./register-command");
|
|
7
|
+
const upgrade_command_1 = require("./upgrade-command");
|
|
8
|
+
const license_api_client_1 = require("./license-api-client");
|
|
9
|
+
const license_key_1 = require("../license/license-key");
|
|
10
|
+
const public_key_1 = require("../license/public-key");
|
|
11
|
+
const license_store_1 = require("../license/license-store");
|
|
12
|
+
function printHelp() {
|
|
13
|
+
console.log([
|
|
14
|
+
"EGA V9 CLI",
|
|
15
|
+
"",
|
|
16
|
+
"Usage:",
|
|
17
|
+
" ega-v9 register",
|
|
18
|
+
" ega-v9 upgrade",
|
|
19
|
+
" ega-v9 --help",
|
|
20
|
+
"",
|
|
21
|
+
"Commands:",
|
|
22
|
+
" register Activate a 90-day Evaluation License",
|
|
23
|
+
" upgrade Request or activate a Commercial License"
|
|
24
|
+
].join("\n"));
|
|
25
|
+
}
|
|
26
|
+
async function main() {
|
|
27
|
+
const command = process.argv[2];
|
|
28
|
+
if (command === "--help" ||
|
|
29
|
+
command === "-h" ||
|
|
30
|
+
!command) {
|
|
31
|
+
printHelp();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (command === "upgrade") {
|
|
35
|
+
const exitCode = await (0, upgrade_command_1.runUpgradeCommand)();
|
|
36
|
+
process.exitCode =
|
|
37
|
+
exitCode;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (command !== "register") {
|
|
41
|
+
console.error(`Unknown command: ${command}`);
|
|
42
|
+
printHelp();
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const apiBaseUrl = process.env
|
|
47
|
+
.EGA_V9_LICENSE_API_URL ??
|
|
48
|
+
"https://lcm3.com";
|
|
49
|
+
const publicKey = (0, public_key_1.loadEvaluationLicensePublicKey)();
|
|
50
|
+
const licenseApi = (0, license_api_client_1.createLicenseApiClient)({
|
|
51
|
+
baseUrl: apiBaseUrl
|
|
52
|
+
});
|
|
53
|
+
const readline = (0, promises_1.createInterface)({
|
|
54
|
+
input: process_1.stdin,
|
|
55
|
+
output: process_1.stdout
|
|
56
|
+
});
|
|
57
|
+
try {
|
|
58
|
+
await (0, register_command_1.runRegisterCommand)({
|
|
59
|
+
ask: async (question) => readline.question(question),
|
|
60
|
+
issueEvaluationLicense: input => licenseApi
|
|
61
|
+
.issueEvaluationLicense(input),
|
|
62
|
+
verifyEvaluationLicenseKey: evaluationLicenseKey => (0, license_key_1.verifyEvaluationLicenseKey)(evaluationLicenseKey, publicKey),
|
|
63
|
+
saveEvaluationLicenseKey: (evaluationLicenseKey, options) => (0, license_store_1.saveEvaluationLicenseKey)(evaluationLicenseKey, options),
|
|
64
|
+
write: message => console.log(message)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
readline.close();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
main().catch((error) => {
|
|
72
|
+
console.error(error instanceof Error
|
|
73
|
+
? error.message
|
|
74
|
+
: "Unexpected EGA V9 CLI error.");
|
|
75
|
+
process.exitCode = 1;
|
|
76
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EGARegistrationInput, EGARegistrationResponse } from "./register-command";
|
|
2
|
+
export type EGALicenseApiClientOptions = {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
timeoutMilliseconds?: number;
|
|
5
|
+
fetchImplementation?: typeof fetch;
|
|
6
|
+
};
|
|
7
|
+
export declare class EGALicenseApiError extends Error {
|
|
8
|
+
readonly code: "EGA_LICENSE_API_CONFIG" | "EGA_LICENSE_API_NETWORK" | "EGA_LICENSE_API_RESPONSE";
|
|
9
|
+
readonly statusCode?: number;
|
|
10
|
+
readonly remoteCode?: string;
|
|
11
|
+
constructor(args: {
|
|
12
|
+
code: EGALicenseApiError["code"];
|
|
13
|
+
message: string;
|
|
14
|
+
statusCode?: number;
|
|
15
|
+
remoteCode?: string;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export declare function createLicenseApiClient(options: EGALicenseApiClientOptions): {
|
|
19
|
+
issueEvaluationLicense(input: EGARegistrationInput): Promise<EGARegistrationResponse>;
|
|
20
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EGALicenseApiError = void 0;
|
|
4
|
+
exports.createLicenseApiClient = createLicenseApiClient;
|
|
5
|
+
class EGALicenseApiError extends Error {
|
|
6
|
+
constructor(args) {
|
|
7
|
+
super(`[${args.code}] ${args.message}`);
|
|
8
|
+
this.name =
|
|
9
|
+
"EGALicenseApiError";
|
|
10
|
+
this.code =
|
|
11
|
+
args.code;
|
|
12
|
+
this.statusCode =
|
|
13
|
+
args.statusCode;
|
|
14
|
+
this.remoteCode =
|
|
15
|
+
args.remoteCode;
|
|
16
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.EGALicenseApiError = EGALicenseApiError;
|
|
20
|
+
function normalizeBaseUrl(value) {
|
|
21
|
+
if (typeof value !== "string" ||
|
|
22
|
+
value.trim().length === 0) {
|
|
23
|
+
throw new EGALicenseApiError({
|
|
24
|
+
code: "EGA_LICENSE_API_CONFIG",
|
|
25
|
+
message: "The License API base URL is required."
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
let url;
|
|
29
|
+
try {
|
|
30
|
+
url = new URL(value.trim());
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new EGALicenseApiError({
|
|
34
|
+
code: "EGA_LICENSE_API_CONFIG",
|
|
35
|
+
message: "The License API base URL is invalid."
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (url.protocol !== "https:" &&
|
|
39
|
+
!(url.protocol === "http:" &&
|
|
40
|
+
(url.hostname ===
|
|
41
|
+
"127.0.0.1" ||
|
|
42
|
+
url.hostname ===
|
|
43
|
+
"localhost"))) {
|
|
44
|
+
throw new EGALicenseApiError({
|
|
45
|
+
code: "EGA_LICENSE_API_CONFIG",
|
|
46
|
+
message: "The License API must use HTTPS, except for localhost development."
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return url
|
|
50
|
+
.toString()
|
|
51
|
+
.replace(/\/$/, "");
|
|
52
|
+
}
|
|
53
|
+
function createLicenseApiClient(options) {
|
|
54
|
+
const baseUrl = normalizeBaseUrl(options.baseUrl);
|
|
55
|
+
const timeoutMilliseconds = options.timeoutMilliseconds ??
|
|
56
|
+
10000;
|
|
57
|
+
if (!Number.isInteger(timeoutMilliseconds) ||
|
|
58
|
+
timeoutMilliseconds < 1) {
|
|
59
|
+
throw new EGALicenseApiError({
|
|
60
|
+
code: "EGA_LICENSE_API_CONFIG",
|
|
61
|
+
message: "timeoutMilliseconds must be a positive integer."
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const fetchImplementation = options.fetchImplementation ??
|
|
65
|
+
fetch;
|
|
66
|
+
return {
|
|
67
|
+
async issueEvaluationLicense(input) {
|
|
68
|
+
const controller = new AbortController();
|
|
69
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMilliseconds);
|
|
70
|
+
try {
|
|
71
|
+
let response;
|
|
72
|
+
try {
|
|
73
|
+
response =
|
|
74
|
+
await fetchImplementation(`${baseUrl}/api/licenses/evaluation`, {
|
|
75
|
+
method: "POST",
|
|
76
|
+
headers: {
|
|
77
|
+
"content-type": "application/json",
|
|
78
|
+
"accept": "application/json"
|
|
79
|
+
},
|
|
80
|
+
body: JSON.stringify(input),
|
|
81
|
+
signal: controller.signal
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
throw new EGALicenseApiError({
|
|
86
|
+
code: "EGA_LICENSE_API_NETWORK",
|
|
87
|
+
message: error instanceof Error
|
|
88
|
+
? error.message
|
|
89
|
+
: "Unable to connect to the License API."
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
let body;
|
|
93
|
+
try {
|
|
94
|
+
body =
|
|
95
|
+
await response.json();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
throw new EGALicenseApiError({
|
|
99
|
+
code: "EGA_LICENSE_API_RESPONSE",
|
|
100
|
+
message: "The License API returned invalid JSON.",
|
|
101
|
+
statusCode: response.status
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
const errorBody = body;
|
|
106
|
+
throw new EGALicenseApiError({
|
|
107
|
+
code: "EGA_LICENSE_API_RESPONSE",
|
|
108
|
+
message: errorBody.error?.message ??
|
|
109
|
+
"The License API rejected the request.",
|
|
110
|
+
statusCode: response.status,
|
|
111
|
+
remoteCode: errorBody.error?.code
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const successBody = body;
|
|
115
|
+
if (typeof successBody
|
|
116
|
+
.evaluationLicenseKey !==
|
|
117
|
+
"string" ||
|
|
118
|
+
successBody
|
|
119
|
+
.evaluationLicenseKey
|
|
120
|
+
.trim()
|
|
121
|
+
.length === 0) {
|
|
122
|
+
throw new EGALicenseApiError({
|
|
123
|
+
code: "EGA_LICENSE_API_RESPONSE",
|
|
124
|
+
message: "The License API response does not contain an Evaluation License Key.",
|
|
125
|
+
statusCode: response.status
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
evaluationLicenseKey: successBody
|
|
130
|
+
.evaluationLicenseKey
|
|
131
|
+
.trim()
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
clearTimeout(timeout);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { EGAEvaluationLicense } from "../license/types";
|
|
2
|
+
export type EGARegistrationInput = {
|
|
3
|
+
contactName: string;
|
|
4
|
+
companyName: string;
|
|
5
|
+
workEmail: string;
|
|
6
|
+
};
|
|
7
|
+
export type EGARegistrationResponse = {
|
|
8
|
+
evaluationLicenseKey: string;
|
|
9
|
+
};
|
|
10
|
+
export type EGARegisterCommandDependencies = {
|
|
11
|
+
ask: (question: string) => Promise<string>;
|
|
12
|
+
issueEvaluationLicense: (input: EGARegistrationInput) => Promise<EGARegistrationResponse>;
|
|
13
|
+
verifyEvaluationLicenseKey: (evaluationLicenseKey: string) => EGAEvaluationLicense;
|
|
14
|
+
saveEvaluationLicenseKey: (evaluationLicenseKey: string, options?: {
|
|
15
|
+
overwrite?: boolean;
|
|
16
|
+
}) => string;
|
|
17
|
+
write: (message: string) => void;
|
|
18
|
+
overwrite?: boolean;
|
|
19
|
+
};
|
|
20
|
+
export type EGARegisterCommandResult = {
|
|
21
|
+
license: EGAEvaluationLicense;
|
|
22
|
+
licensePath: string;
|
|
23
|
+
};
|
|
24
|
+
export declare class EGARegisterCommandError extends Error {
|
|
25
|
+
readonly code: "EGA_REGISTER_INPUT" | "EGA_REGISTER_SERVICE" | "EGA_REGISTER_RESPONSE";
|
|
26
|
+
constructor(code: EGARegisterCommandError["code"], message: string);
|
|
27
|
+
}
|
|
28
|
+
export declare function runRegisterCommand(dependencies: EGARegisterCommandDependencies): Promise<EGARegisterCommandResult>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EGARegisterCommandError = void 0;
|
|
4
|
+
exports.runRegisterCommand = runRegisterCommand;
|
|
5
|
+
class EGARegisterCommandError extends Error {
|
|
6
|
+
constructor(code, message) {
|
|
7
|
+
super(`[${code}] ${message}`);
|
|
8
|
+
this.name =
|
|
9
|
+
"EGARegisterCommandError";
|
|
10
|
+
this.code =
|
|
11
|
+
code;
|
|
12
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.EGARegisterCommandError = EGARegisterCommandError;
|
|
16
|
+
function requireNonEmpty(value, fieldName) {
|
|
17
|
+
if (typeof value !== "string" ||
|
|
18
|
+
value.trim().length === 0) {
|
|
19
|
+
throw new EGARegisterCommandError("EGA_REGISTER_INPUT", `${fieldName} is required.`);
|
|
20
|
+
}
|
|
21
|
+
return value.trim();
|
|
22
|
+
}
|
|
23
|
+
function validateWorkEmail(value) {
|
|
24
|
+
const workEmail = requireNonEmpty(value, "Work Email").toLowerCase();
|
|
25
|
+
const simpleEmailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
26
|
+
if (!simpleEmailPattern.test(workEmail)) {
|
|
27
|
+
throw new EGARegisterCommandError("EGA_REGISTER_INPUT", "Work Email must be a valid email address.");
|
|
28
|
+
}
|
|
29
|
+
return workEmail;
|
|
30
|
+
}
|
|
31
|
+
function formatDate(value) {
|
|
32
|
+
const date = new Date(value);
|
|
33
|
+
if (Number.isNaN(date.getTime())) {
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
return date
|
|
37
|
+
.toISOString()
|
|
38
|
+
.slice(0, 10);
|
|
39
|
+
}
|
|
40
|
+
function calculateDaysRemaining(expiresAt, now = new Date()) {
|
|
41
|
+
const expirationDate = new Date(expiresAt);
|
|
42
|
+
if (Number.isNaN(expirationDate.getTime())) {
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
const dayMilliseconds = 24 * 60 * 60 * 1000;
|
|
46
|
+
return Math.max(0, Math.ceil((expirationDate.getTime() -
|
|
47
|
+
now.getTime()) /
|
|
48
|
+
dayMilliseconds));
|
|
49
|
+
}
|
|
50
|
+
async function runRegisterCommand(dependencies) {
|
|
51
|
+
dependencies.write("");
|
|
52
|
+
dependencies.write("Welcome to EGA V9");
|
|
53
|
+
dependencies.write("");
|
|
54
|
+
dependencies.write("Activate your 90-day Evaluation License.");
|
|
55
|
+
dependencies.write("No credit card required.");
|
|
56
|
+
dependencies.write("");
|
|
57
|
+
const contactName = requireNonEmpty(await dependencies.ask("Contact Name: "), "Contact Name");
|
|
58
|
+
const companyName = requireNonEmpty(await dependencies.ask("Company Name: "), "Company Name");
|
|
59
|
+
const workEmail = validateWorkEmail(await dependencies.ask("Work Email: "));
|
|
60
|
+
let response;
|
|
61
|
+
try {
|
|
62
|
+
response =
|
|
63
|
+
await dependencies
|
|
64
|
+
.issueEvaluationLicense({
|
|
65
|
+
contactName,
|
|
66
|
+
companyName,
|
|
67
|
+
workEmail
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new EGARegisterCommandError("EGA_REGISTER_SERVICE", `Unable to activate the Evaluation License: ${error instanceof Error
|
|
72
|
+
? error.message
|
|
73
|
+
: "unknown service error"}`);
|
|
74
|
+
}
|
|
75
|
+
if (!response ||
|
|
76
|
+
typeof response.evaluationLicenseKey !==
|
|
77
|
+
"string" ||
|
|
78
|
+
response.evaluationLicenseKey.trim()
|
|
79
|
+
.length === 0) {
|
|
80
|
+
throw new EGARegisterCommandError("EGA_REGISTER_RESPONSE", "The License Service returned an invalid Evaluation License Key.");
|
|
81
|
+
}
|
|
82
|
+
const evaluationLicenseKey = response.evaluationLicenseKey.trim();
|
|
83
|
+
const license = dependencies
|
|
84
|
+
.verifyEvaluationLicenseKey(evaluationLicenseKey);
|
|
85
|
+
const licensePath = dependencies
|
|
86
|
+
.saveEvaluationLicenseKey(evaluationLicenseKey, {
|
|
87
|
+
overwrite: dependencies.overwrite ??
|
|
88
|
+
false
|
|
89
|
+
});
|
|
90
|
+
dependencies.write("");
|
|
91
|
+
dependencies.write("✓ Evaluation License Activated");
|
|
92
|
+
dependencies.write("");
|
|
93
|
+
dependencies.write(`Issued: ${formatDate(license.issuedAt)}`);
|
|
94
|
+
dependencies.write(`Expires: ${formatDate(license.expiresAt)}`);
|
|
95
|
+
dependencies.write(`Days Remaining: ${calculateDaysRemaining(license.expiresAt)}`);
|
|
96
|
+
dependencies.write("");
|
|
97
|
+
dependencies.write(`License stored: ${licensePath}`);
|
|
98
|
+
dependencies.write("");
|
|
99
|
+
dependencies.write("Happy Building.");
|
|
100
|
+
return {
|
|
101
|
+
license,
|
|
102
|
+
licensePath
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runUpgradeCommand = runUpgradeCommand;
|
|
4
|
+
const license_key_1 = require("../license/license-key");
|
|
5
|
+
const license_store_1 = require("../license/license-store");
|
|
6
|
+
const public_key_1 = require("../license/public-key");
|
|
7
|
+
const commercial_api_client_1 = require("./commercial-api-client");
|
|
8
|
+
async function runUpgradeCommand(options = {}) {
|
|
9
|
+
const writeLine = options.writeLine ??
|
|
10
|
+
console.log;
|
|
11
|
+
const installedLicenseKey = (0, license_store_1.readEvaluationLicenseKey)();
|
|
12
|
+
if (!installedLicenseKey) {
|
|
13
|
+
writeLine("No EGA V9 License Key is installed.");
|
|
14
|
+
writeLine("Run `npx ega-v9 register` first.");
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
const apiBaseUrl = options.apiBaseUrl ??
|
|
18
|
+
process.env
|
|
19
|
+
.EGA_V9_LICENSE_API_URL;
|
|
20
|
+
if (!apiBaseUrl) {
|
|
21
|
+
writeLine("EGA V9 License Service URL is not configured.");
|
|
22
|
+
return 1;
|
|
23
|
+
}
|
|
24
|
+
const client = (0, commercial_api_client_1.createCommercialApiClient)({
|
|
25
|
+
apiBaseUrl
|
|
26
|
+
});
|
|
27
|
+
try {
|
|
28
|
+
const currentStatus = await client.getStatus(installedLicenseKey);
|
|
29
|
+
if (currentStatus.status ===
|
|
30
|
+
"approved" &&
|
|
31
|
+
currentStatus
|
|
32
|
+
.commercialLicenseKey) {
|
|
33
|
+
const commercialLicense = (0, license_key_1.verifyLicenseKey)(currentStatus
|
|
34
|
+
.commercialLicenseKey, (0, public_key_1.loadEvaluationLicensePublicKey)());
|
|
35
|
+
if (commercialLicense
|
|
36
|
+
.licenseKind !==
|
|
37
|
+
"commercial") {
|
|
38
|
+
throw new Error("The returned License is not Commercial.");
|
|
39
|
+
}
|
|
40
|
+
(0, license_store_1.saveEvaluationLicenseKey)(currentStatus
|
|
41
|
+
.commercialLicenseKey, {
|
|
42
|
+
overwrite: true
|
|
43
|
+
});
|
|
44
|
+
writeLine("");
|
|
45
|
+
writeLine("✓ Commercial License Activated");
|
|
46
|
+
writeLine("");
|
|
47
|
+
writeLine(`Company: ${commercialLicense.companyName}`);
|
|
48
|
+
writeLine(`License ID: ${commercialLicense.licenseId}`);
|
|
49
|
+
writeLine(`Issued: ${commercialLicense.issuedAt.slice(0, 10)}`);
|
|
50
|
+
writeLine(commercialLicense.expiresAt
|
|
51
|
+
? `Expires: ${commercialLicense.expiresAt.slice(0, 10)}`
|
|
52
|
+
: "Expires: No fixed expiration");
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
if (currentStatus.status ===
|
|
56
|
+
"pending") {
|
|
57
|
+
writeLine("");
|
|
58
|
+
writeLine("Commercial License request is under review.");
|
|
59
|
+
writeLine(`Request ID: ${currentStatus.requestId}`);
|
|
60
|
+
writeLine("");
|
|
61
|
+
writeLine("Run `npx ega-v9 upgrade` again after LCM confirms your Commercial agreement.");
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
if (currentStatus.status ===
|
|
65
|
+
"rejected") {
|
|
66
|
+
writeLine("");
|
|
67
|
+
writeLine("Commercial License request was not approved.");
|
|
68
|
+
if (currentStatus
|
|
69
|
+
.rejectionReason) {
|
|
70
|
+
writeLine(`Reason: ${currentStatus.rejectionReason}`);
|
|
71
|
+
}
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
const requestResult = await client.requestUpgrade(installedLicenseKey);
|
|
75
|
+
writeLine("");
|
|
76
|
+
writeLine("✓ Commercial License Request Submitted");
|
|
77
|
+
writeLine("");
|
|
78
|
+
writeLine(`Request ID: ${requestResult.requestId}`);
|
|
79
|
+
writeLine("Status: Pending LCM review");
|
|
80
|
+
writeLine("");
|
|
81
|
+
writeLine("LCM will contact your registered Work Email regarding the Commercial agreement.");
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
writeLine(error instanceof Error
|
|
86
|
+
? error.message
|
|
87
|
+
: "Unable to process the Commercial License request.");
|
|
88
|
+
return 1;
|
|
89
|
+
}
|
|
90
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -185,4 +185,5 @@ declare function createGuard(options?: EGAGuardOptions): (req: EGAGuardRequest,
|
|
|
185
185
|
export declare const ega: Readonly<{
|
|
186
186
|
guard: typeof createGuard;
|
|
187
187
|
}>;
|
|
188
|
-
export {};
|
|
188
|
+
export { EGARuntimeAdmissionError, assertRuntimeLicenseAdmission, evaluateRuntimeAdmission } from "./license/runtime-admission";
|
|
189
|
+
export type { EGARuntimeAdmissionDecision, EGARuntimeAdmissionDependencies, EGARuntimeAdmissionReason } from "./license/runtime-admission";
|