@endo-ui/license 1.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/LICENSE.md ADDED
@@ -0,0 +1,381 @@
1
+ # EndoUI / @endo-ui Software License Agreement
2
+
3
+ **Effective Date: August 10, 2026**
4
+
5
+ This EndoUI / @endo-ui Software License Agreement (the **“Agreement”**) is entered into between **ECAP Software LLC**, doing business as ECAP Software (**“ECAP,” “we,” “us,” or “our”**), and the individual or legal entity that obtains, installs, accesses, or uses EndoUI (**“Licensee,” “you,” or “your”**).
6
+
7
+ By installing, accessing, copying, downloading, or using EndoUI, you agree to be bound by this Agreement.
8
+
9
+ If you are using EndoUI on behalf of a company, organization, governmental entity, or other legal entity, you represent and warrant that you have authority to bind that entity to this Agreement.
10
+
11
+ If you do not agree to this Agreement, you may not install, access, copy, or use EndoUI.
12
+
13
+ ## 1. Definitions
14
+
15
+ ### 1.1 EndoUI
16
+
17
+ **“EndoUI”** means ECAP's proprietary software library and related materials distributed under the names **EndoUI**, **Endo UI**, **Endo-UI**, or through packages within the **`@endo-ui` npm namespace**, including applicable source code, object code, compiled code, npm packages, UI components, development tools, documentation, examples, templates, updates, patches, modifications, and related materials distributed by ECAP.
18
+
19
+ EndoUI is proprietary software and is **licensed, not sold**.
20
+
21
+ ### 1.2 Seat
22
+
23
+ A **“Seat”** means authorization for one identified individual developer or other authorized individual to use EndoUI for software-development purposes.
24
+
25
+ A Seat is assigned to a person, not to a particular computer or device.
26
+
27
+ ### 1.3 Major Version
28
+
29
+ A **“Major Version”** means the first numeric component of an EndoUI semantic version.
30
+
31
+ For example:
32
+
33
+ - `1.0.0` is Major Version 1;
34
+ - `1.7.4` is Major Version 1;
35
+ - `2.0.0` is Major Version 2.
36
+
37
+ ### 1.4 Application
38
+
39
+ An **“Application”** means software, a website, service, product, system, or other work developed by or for Licensee that incorporates or makes use of EndoUI.
40
+
41
+ ## 2. Ownership
42
+
43
+ EndoUI and all intellectual-property rights in EndoUI are owned by ECAP or its licensors.
44
+
45
+ Except for third-party materials expressly governed by separate license terms, ECAP retains all right, title, and interest in and to EndoUI, including all copyrights, patents, trade secrets, trademarks, proprietary rights, and other intellectual-property rights.
46
+
47
+ No ownership rights in EndoUI are transferred to Licensee under this Agreement.
48
+
49
+ Licensee retains ownership of its own Applications and original materials, excluding EndoUI and other ECAP-owned materials incorporated into them.
50
+
51
+ ## 3. License Grant
52
+
53
+ Subject to:
54
+
55
+ 1. payment of all applicable fees;
56
+ 2. the license rights recorded or issued by ECAP; and
57
+ 3. Licensee's continued compliance with this Agreement,
58
+
59
+ ECAP grants Licensee a limited, non-exclusive, non-transferable, non-sublicensable license to:
60
+
61
+ a. install and use EndoUI by the number of authorized Seats purchased or otherwise granted by ECAP;
62
+
63
+ b. use EndoUI to design, develop, test, build, maintain, and support Applications;
64
+
65
+ c. incorporate EndoUI components into Applications;
66
+
67
+ d. modify EndoUI configuration, styling, composition, and integration as reasonably necessary to create Licensee's Applications; and
68
+
69
+ e. distribute Applications containing compiled, bundled, minified, transformed, or otherwise incorporated portions of EndoUI as permitted by this Agreement.
70
+
71
+ Licensee receives only those rights expressly granted under this Agreement.
72
+
73
+ ## 4. Organizational Licensing
74
+
75
+ Unless ECAP expressly agrees otherwise in writing, an EndoUI license is issued to the legal entity identified in the applicable order, invoice, purchase record, license record, subscription, agreement, or other transaction record.
76
+
77
+ One organizational license may authorize multiple Seats.
78
+
79
+ A license issued to one organization may not be shared with an unaffiliated legal entity.
80
+
81
+ Affiliates, subsidiaries, parent companies, contractors, customers, or other third parties are not automatically covered unless expressly included in the applicable license or written agreement.
82
+
83
+ ## 5. Developer Seats
84
+
85
+ Every individual who directly uses EndoUI for development must occupy an authorized Seat unless ECAP has granted that organization a license expressly providing unlimited users.
86
+
87
+ Seats:
88
+
89
+ - are assigned to individual users;
90
+ - may not be concurrently shared among multiple individuals;
91
+ - may be reassigned when personnel or responsibilities change;
92
+ - may not exceed the quantity purchased or granted; and
93
+ - are associated with Licensee's organizational license.
94
+
95
+ A licensed developer may use EndoUI from multiple computers or devices as reasonably necessary for that individual's work.
96
+
97
+ **Seats are not machine licenses.**
98
+
99
+ A developer does not require additional Seats merely because that developer uses a workstation, laptop, remote development environment, virtual machine, development container, or similar secondary development environment.
100
+
101
+ Automated CI/CD, build, testing, deployment, and hosting systems do not independently consume a Seat merely because EndoUI is processed by those systems.
102
+
103
+ ## 6. Contractors
104
+
105
+ Licensee may permit a contractor to use EndoUI on Licensee's behalf only if:
106
+
107
+ 1. the contractor occupies an authorized Seat unless the applicable license provides unlimited Seats;
108
+ 2. the contractor uses EndoUI solely for work performed for Licensee;
109
+ 3. the contractor is subject to confidentiality and intellectual-property obligations consistent with this Agreement; and
110
+ 4. the contractor ceases using Licensee's EndoUI license when the authorized engagement ends.
111
+
112
+ A contractor may not use Licensee's EndoUI license for unrelated customers or projects.
113
+
114
+ ## 7. Application Distribution Rights
115
+
116
+ Subject to this Agreement, Licensee may distribute Applications developed using EndoUI to an unlimited number of application users or customers unless a separate written agreement states otherwise.
117
+
118
+ Application end users do **not** require EndoUI developer Seats merely because they use an Application developed with EndoUI.
119
+
120
+ Licensee may distribute production Application code containing EndoUI where EndoUI is compiled, bundled, minified, transformed, tree-shaken, packaged, or otherwise incorporated as part of the Application.
121
+
122
+ Licensee may not intentionally distribute EndoUI in a manner designed to allow recipients to extract, reuse, or consume EndoUI as an independent development library.
123
+
124
+ ## 8. Major-Version Licensing
125
+
126
+ EndoUI license rights are granted by Major Version.
127
+
128
+ Authorization for Major Version 1 authorizes Licensee to use EndoUI releases within the `1.x.x` release family.
129
+
130
+ For example, authorization for Major Version 1 includes:
131
+
132
+ - `1.0.0`;
133
+ - `1.1.0`;
134
+ - `1.8.4`; and
135
+ - other authorized `1.x.x` releases.
136
+
137
+ It does **not** automatically authorize EndoUI `2.x.x`.
138
+
139
+ Authorization for a subsequent Major Version may require an upgrade purchase, additional fees, a subscription entitlement, a partner entitlement, an enterprise agreement, or another authorization from ECAP.
140
+
141
+ Unless otherwise stated in the applicable order or agreement, Licensee may continue using a Major Version for which it has received a perpetual license entitlement even after ECAP releases a newer Major Version.
142
+
143
+ Release of a new Major Version does not revoke Licensee's rights to continue using an earlier Major Version for which Licensee retains a valid entitlement.
144
+
145
+ ## 9. Updates, Patches, and Minor Releases
146
+
147
+ Authorization for a Major Version includes releases within that same major release family that ECAP makes available to Licensee.
148
+
149
+ ECAP may provide bug fixes, patches, security updates, feature releases, compatibility updates, or other improvements.
150
+
151
+ ECAP does not guarantee that maintenance, technical support, security fixes, dependency updates, or platform compatibility will continue indefinitely for older Major Versions unless a separate written agreement provides otherwise.
152
+
153
+ ## 10. Partner Licenses
154
+
155
+ ECAP may issue special EndoUI licenses to authorized partners.
156
+
157
+ A Partner License may include unlimited Seats, access to specified Major Versions, special pricing, development rights, demonstration rights, internal-use rights, or other benefits specified by ECAP.
158
+
159
+ Partner status and Partner License rights remain subject to the applicable partnership agreement, program requirements, or written authorization from ECAP.
160
+
161
+ Termination or expiration of a partnership may affect future partner entitlements as specified in the applicable agreement.
162
+
163
+ ## 11. Internal Licenses
164
+
165
+ ECAP may issue Internal Licenses for its own employees, contractors, demonstrations, testing, development, CI/CD, internal systems, and other authorized business purposes.
166
+
167
+ Internal Licenses may contain different Seat, expiration, or Major Version restrictions from commercial licenses.
168
+
169
+ ## 12. License Verification
170
+
171
+ EndoUI may use technical measures to verify compliance with this Agreement.
172
+
173
+ License verification may include verification of:
174
+
175
+ - license validity;
176
+ - license status;
177
+ - licensed product;
178
+ - organizational license;
179
+ - authorized users;
180
+ - purchased Seat quantities;
181
+ - authorized Major Versions;
182
+ - license entitlements;
183
+ - suspension status;
184
+ - expiration status where applicable; and
185
+ - other licensing conditions.
186
+
187
+ Licensee agrees not to intentionally disable, defeat, bypass, tamper with, circumvent, reverse, falsify, or interfere with EndoUI's license-verification mechanisms.
188
+
189
+ ECAP may use reasonable cached authorization, signed authorization, offline authorization, grace periods, periodic revalidation, or similar mechanisms to reduce unnecessary disruption caused by temporary connectivity failures.
190
+
191
+ License verification does not authorize ECAP to inspect unrelated proprietary Application source code or customer content.
192
+
193
+ ## 13. Restrictions
194
+
195
+ Except as expressly permitted by this Agreement, Licensee may not:
196
+
197
+ 1. sell, rent, lease, sublicense, publish, distribute, or otherwise make EndoUI available as a standalone library, package, SDK, component collection, development toolkit, or similar product;
198
+ 2. redistribute a package within the `@endo-ui` namespace for independent use by another party;
199
+ 3. create and distribute a materially equivalent repackaging of EndoUI intended to substitute for EndoUI itself;
200
+ 4. provide EndoUI to another organization for that organization's independent development use;
201
+ 5. share license credentials or Seats for the purpose of exceeding authorized Seat limits;
202
+ 6. use a license issued to another organization without ECAP's authorization;
203
+ 7. use an EndoUI Major Version for which Licensee does not hold the required entitlement;
204
+ 8. remove, obscure, conceal, or alter proprietary, copyright, trademark, attribution, or license notices contained in EndoUI;
205
+ 9. circumvent or interfere with technical licensing controls;
206
+ 10. represent EndoUI as software owned or authored by Licensee;
207
+ 11. publish ECAP confidential source code except as expressly permitted by this Agreement; or
208
+ 12. use EndoUI in violation of applicable law.
209
+
210
+ Nothing in this Agreement prohibits Licensee from independently developing software that does not unlawfully copy, disclose, or misuse EndoUI or ECAP Confidential Information.
211
+
212
+ ## 14. Competing Development Products
213
+
214
+ Without ECAP's prior written authorization, Licensee may not use EndoUI source code or substantial portions of EndoUI to create or distribute a standalone reusable UI component library, SDK, framework, or development product whose primary purpose is to replace or directly compete with EndoUI.
215
+
216
+ This restriction does not prohibit Licensee from developing ordinary Applications, design systems, internal component abstractions, or application-specific UI components using EndoUI as permitted under this Agreement.
217
+
218
+ ## 15. Third-Party Software
219
+
220
+ EndoUI may include, depend upon, or interoperate with third-party software.
221
+
222
+ Third-party software may be governed by separate open-source licenses, commercial terms, privacy terms, or other agreements.
223
+
224
+ Those terms continue to govern the applicable third-party software.
225
+
226
+ Nothing in this Agreement is intended to restrict rights granted under an applicable third-party open-source license.
227
+
228
+ ## 16. Confidentiality
229
+
230
+ Non-public EndoUI materials may constitute ECAP Confidential Information, including non-public source code, private packages, unreleased features, internal documentation, license credentials, product tokens, security information, and materials identified as confidential.
231
+
232
+ Licensee will use reasonable measures to protect ECAP Confidential Information from unauthorized use or disclosure.
233
+
234
+ Confidentiality obligations do not apply to information Licensee can demonstrate:
235
+
236
+ a. became publicly available without violation of this Agreement;
237
+
238
+ b. was lawfully known without confidentiality restriction before disclosure;
239
+
240
+ c. was independently developed without use of ECAP Confidential Information; or
241
+
242
+ d. was lawfully obtained from another party without confidentiality restriction.
243
+
244
+ ## 17. License Credentials
245
+
246
+ License credentials provided to Licensee are intended solely for Licensee's authorized use.
247
+
248
+ Licensee must use reasonable measures to protect license credentials from unauthorized disclosure.
249
+
250
+ Licensee must promptly notify ECAP if it becomes aware that a license credential has been compromised, publicly exposed, stolen, or used without authorization.
251
+
252
+ ECAP may rotate, replace, revoke, or suspend compromised credentials.
253
+
254
+ ## 18. Support
255
+
256
+ Technical support, maintenance, service levels, response times, update commitments, and other support obligations apply only if included in Licensee's purchase, subscription, support plan, enterprise agreement, order, or other written agreement with ECAP.
257
+
258
+ An EndoUI license does not by itself require ECAP to provide custom development, consulting, implementation, integration, migration, or other professional services.
259
+
260
+ ## 19. Suspension
261
+
262
+ ECAP may suspend an EndoUI license if ECAP reasonably determines that:
263
+
264
+ - applicable fees are materially overdue;
265
+ - the license is being used fraudulently;
266
+ - Licensee materially exceeds authorized Seat limits;
267
+ - license credentials have been compromised;
268
+ - the license is being shared with unauthorized entities;
269
+ - Licensee is using unauthorized Major Versions;
270
+ - Licensee materially breaches this Agreement; or
271
+ - suspension is reasonably necessary to protect ECAP systems or comply with applicable law.
272
+
273
+ Where reasonably practicable, ECAP will provide notice and an opportunity to cure a remediable material breach before permanent termination.
274
+
275
+ Suspension does not transfer ownership of Licensee Applications to ECAP.
276
+
277
+ ## 20. Termination
278
+
279
+ Licensee may cease using EndoUI at any time.
280
+
281
+ ECAP may terminate this Agreement or an applicable license if Licensee materially breaches this Agreement and fails to cure the breach within a reasonable period following notice, where the breach is capable of cure.
282
+
283
+ Upon termination of Licensee's rights, Licensee must cease unauthorized use of EndoUI and delete copies that Licensee is no longer authorized to retain.
284
+
285
+ Unless otherwise required by law or a separate agreement, termination does not require Licensee to withdraw Applications previously and lawfully distributed under this Agreement solely because those Applications contain permitted compiled or bundled EndoUI code.
286
+
287
+ Sections that by their nature should survive termination will survive, including provisions concerning ownership, restrictions, confidentiality, disclaimers, limitations of liability, indemnification, and accrued payment obligations.
288
+
289
+ ## 21. Feedback
290
+
291
+ If Licensee voluntarily provides suggestions, ideas, recommendations, improvements, or other feedback regarding EndoUI, Licensee grants ECAP a perpetual, irrevocable, worldwide, royalty-free right to use, reproduce, modify, and incorporate that feedback for any lawful purpose.
292
+
293
+ This provision does not grant ECAP ownership of Licensee's Applications, confidential information, proprietary source code, customer information, or business data.
294
+
295
+ ## 22. Disclaimer of Warranties
296
+
297
+ **TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, ENDOUI IS PROVIDED “AS IS” AND “AS AVAILABLE.”**
298
+
299
+ Except for an express warranty contained in a separate written agreement signed by ECAP, ECAP disclaims all express, implied, statutory, and other warranties, including warranties of merchantability, fitness for a particular purpose, title, non-infringement, quiet enjoyment, compatibility, and warranties arising from course of dealing or usage of trade.
300
+
301
+ ECAP does not warrant that EndoUI will be error-free, operate without interruption, meet every Licensee requirement, remain compatible with every browser, framework, dependency, platform, operating system, or tool, or be free from vulnerabilities.
302
+
303
+ ## 23. Limitation of Liability
304
+
305
+ **TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NEITHER PARTY WILL BE LIABLE UNDER THIS AGREEMENT FOR INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL DAMAGES, OR FOR LOSS OF PROFITS, REVENUE, BUSINESS OPPORTUNITIES, GOODWILL, OR DATA, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.**
306
+
307
+ To the maximum extent permitted by applicable law, ECAP's aggregate liability arising out of or relating to EndoUI or this Agreement will not exceed the amounts paid or payable by Licensee to ECAP for EndoUI during the twelve (12) months immediately preceding the event giving rise to the claim.
308
+
309
+ If Licensee purchased a perpetual license through a one-time payment and no fees were paid during the preceding twelve months, the liability cap will be the amount originally paid for the applicable EndoUI license.
310
+
311
+ Nothing in this Agreement excludes or limits liability that applicable law does not permit to be excluded or limited.
312
+
313
+ ## 24. Indemnification
314
+
315
+ Licensee will defend, indemnify, and hold harmless ECAP and its officers, directors, employees, and agents from third-party claims, damages, liabilities, costs, and reasonable attorneys' fees arising from Licensee's Applications, Licensee's unlawful use of EndoUI, Licensee's material breach of this Agreement, materials supplied by Licensee, or Licensee's violation of applicable law, except to the extent a claim results from ECAP's material breach of this Agreement or infringement arising directly from unmodified EndoUI supplied by ECAP.
316
+
317
+ Any indemnification terms contained in a separately signed agreement between the parties will control over conflicting terms in this section.
318
+
319
+ ## 25. Export Controls and Legal Compliance
320
+
321
+ Licensee will comply with applicable export-control laws, economic sanctions, anti-corruption laws, trade restrictions, and other laws relating to Licensee's use or transfer of EndoUI.
322
+
323
+ Licensee may not export, re-export, transfer, or use EndoUI in violation of applicable law.
324
+
325
+ ## 26. Government Users
326
+
327
+ If EndoUI is acquired by or on behalf of a governmental entity, EndoUI is commercial computer software and commercial computer software documentation and is licensed only with the rights granted under this Agreement except where applicable law requires otherwise.
328
+
329
+ ## 27. Orders and Enterprise Agreements
330
+
331
+ A separate order, order form, enterprise agreement, master services agreement, partnership agreement, negotiated software agreement, or other written contract may modify the rights granted under this Agreement.
332
+
333
+ If a separately signed agreement between ECAP and Licensee conflicts with this Agreement, the separately signed agreement will control to the extent of the conflict.
334
+
335
+ Otherwise, this Agreement governs Licensee's use of EndoUI.
336
+
337
+ ## 28. Changes to License Terms
338
+
339
+ ECAP may revise these license terms for future purchases, renewals, subscriptions, future Major Versions, or future licensing programs.
340
+
341
+ A material modification will not retroactively reduce perpetual rights previously granted and fully paid for an authorized EndoUI Major Version unless:
342
+
343
+ 1. Licensee agrees to the modification; or
344
+ 2. applicable law requires the change.
345
+
346
+ ## 29. Governing Law
347
+
348
+ This Agreement will be governed by the laws of the State of **Texas**, without regard to conflict-of-laws rules.
349
+
350
+ The parties consent to exclusive jurisdiction and venue in the state and federal courts having jurisdiction over **Ellis County, Texas**, except that either party may seek appropriate injunctive or equitable relief in another court having jurisdiction.
351
+
352
+ ## 30. Assignment
353
+
354
+ Licensee may not assign or transfer this Agreement or an EndoUI license without ECAP's prior written consent, except in connection with a merger, acquisition, corporate restructuring, or sale of substantially all assets relating to the licensed business, provided that the successor agrees to be bound by this Agreement.
355
+
356
+ ECAP may assign this Agreement in connection with a merger, acquisition, financing, corporate restructuring, or sale of all or a material portion of its business or assets.
357
+
358
+ ## 31. Severability
359
+
360
+ If any provision of this Agreement is held invalid or unenforceable, that provision will be modified to the minimum extent necessary to make it enforceable where permitted by law.
361
+
362
+ The remaining provisions will remain in full force and effect.
363
+
364
+ ## 32. Waiver
365
+
366
+ Failure to enforce any provision of this Agreement does not waive the right to enforce that provision or another provision later.
367
+
368
+ ## 33. Entire Agreement
369
+
370
+ This Agreement, together with applicable orders, invoices, license records, signed agreements, partnership agreements, and other incorporated written terms, constitutes the agreement governing Licensee's use of EndoUI.
371
+
372
+ ## 34. Contact
373
+
374
+ Questions concerning EndoUI licensing may be directed to:
375
+
376
+ **ECAP Software LLC**
377
+ d/b/a ECAP Software
378
+
379
+ Licensing: **licensing@ecapsoftware.com**
380
+ Website: **https://www.ecapsoftware.com**
381
+
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @endo-ui/license
2
+
3
+ Private Node-only activation and Angular 22 build enforcement for EndoUI. Nothing in this
4
+ package is imported into the browser application or its production runtime.
5
+
6
+ ## Configure an Angular workspace
7
+
8
+ After installing `@endo-ui/core` and this package from the private `@endo-ui` namespace:
9
+
10
+ ```bash
11
+ npx ng add @endo-ui/license
12
+ ```
13
+
14
+ The schematic replaces Angular's application and development-server builders with EndoUI
15
+ wrappers. The wrappers verify a signed local authorization before delegating to Angular's
16
+ official builders.
17
+
18
+ ## Developer activation
19
+
20
+ ```bash
21
+ npx endoui-license activate \
22
+ --developer "jane@customer.com"
23
+ ```
24
+
25
+ The command securely prompts for the customer license key. The email identifies the named
26
+ developer Seat; it is not an EndoUI login account. The customer license key is sent only to
27
+ ECAP's licensing service and is not cached by this package. For non-interactive environments,
28
+ provide it through the protected `ENDOUI_LICENSE_KEY` environment variable.
29
+
30
+ ## CI activation
31
+
32
+ Store `ENDOUI_LICENSE_KEY` in the CI provider's protected secret storage, then run:
33
+
34
+ ```bash
35
+ npx endoui-license ci-activate
36
+ npx ng build
37
+ ```
38
+
39
+ CI authorization does not consume a human Seat. The signed authorization is cached outside the
40
+ application source and remains valid for its bounded offline period.
package/bin/api.js ADDED
@@ -0,0 +1,34 @@
1
+ const DEFAULT_SERVICE_URL = "https://license.ecapsoftware.com";
2
+ async function requestLease(pathname, licenseKey, body) {
3
+ const baseUrl = process.env['ENDOUI_LICENSE_URL'] ?? DEFAULT_SERVICE_URL;
4
+ const response = await fetch(new URL(pathname, baseUrl), {
5
+ method: "POST",
6
+ headers: {
7
+ Accept: "application/json",
8
+ "Content-Type": "application/json",
9
+ Authorization: `License ${licenseKey}`
10
+ },
11
+ body: JSON.stringify(body)
12
+ });
13
+ let value;
14
+ try {
15
+ value = await response.json();
16
+ }
17
+ catch {
18
+ value = undefined;
19
+ }
20
+ if (!response.ok || typeof value?.lease !== "string") {
21
+ const detail = typeof value?.error === "string" ? ` ${value.error}` : "";
22
+ throw new Error(`EndoUI activation failed.${detail}`);
23
+ }
24
+ return value.lease;
25
+ }
26
+ export function activateDeveloper(licenseKey, developerEmail, packageVersion) {
27
+ return requestLease("/v1/endoui/leases/developer", licenseKey, {
28
+ developerEmail,
29
+ packageVersion
30
+ });
31
+ }
32
+ export function activateCi(licenseKey, packageVersion) {
33
+ return requestLease("/v1/endoui/leases/ci", licenseKey, { packageVersion });
34
+ }
@@ -0,0 +1,7 @@
1
+ import { createBuilder } from "@angular-devkit/architect";
2
+ import { buildApplication } from "@angular/build";
3
+ import { verifyAuthorization } from "./verify-authorization.js";
4
+ export default createBuilder(async function* endoUiApplicationBuilder(options, context) {
5
+ await verifyAuthorization();
6
+ yield* buildApplication(options, context);
7
+ });
@@ -0,0 +1,7 @@
1
+ import { createBuilder } from "@angular-devkit/architect";
2
+ import { executeDevServerBuilder } from "@angular/build";
3
+ import { verifyAuthorization } from "./verify-authorization.js";
4
+ export default createBuilder(async function* endoUiDevServerBuilder(options, context) {
5
+ await verifyAuthorization();
6
+ yield* executeDevServerBuilder(options, context);
7
+ });
@@ -0,0 +1,8 @@
1
+ import { resolveEndoUiVersion } from "../package-version.js";
2
+ import { verifyLease } from "../lease.js";
3
+ import { readLease } from "../storage.js";
4
+ export async function verifyAuthorization() {
5
+ const version = resolveEndoUiVersion();
6
+ const major = Number(version.split(".", 1)[0]);
7
+ verifyLease(await readLease(major), version);
8
+ }
package/bin/cli.js ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ import { activateCi, activateDeveloper } from "./api.js";
3
+ import { createInterface } from "node:readline/promises";
4
+ import { Writable } from "node:stream";
5
+ import { verifyLease } from "./lease.js";
6
+ import { resolveEndoUiVersion } from "./package-version.js";
7
+ import { readLease, writeLease } from "./storage.js";
8
+ function argument(name) {
9
+ const index = process.argv.indexOf(name);
10
+ return index >= 0 ? process.argv[index + 1] : undefined;
11
+ }
12
+ function packageMajor(version) {
13
+ const major = Number(version.split(".", 1)[0]);
14
+ if (!Number.isSafeInteger(major) || major <= 0) {
15
+ throw new Error(`EndoUI package version ${version} is not eligible for activation.`);
16
+ }
17
+ return major;
18
+ }
19
+ async function licenseCredential() {
20
+ const configured = process.env['ENDOUI_LICENSE_KEY'];
21
+ if (configured)
22
+ return configured;
23
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
24
+ throw new Error("ENDOUI_LICENSE_KEY is required in non-interactive environments.");
25
+ }
26
+ let muted = false;
27
+ const output = new Writable({
28
+ write(chunk, encoding, callback) {
29
+ if (!muted)
30
+ process.stdout.write(chunk, encoding);
31
+ callback();
32
+ }
33
+ });
34
+ const prompt = createInterface({ input: process.stdin, output, terminal: true });
35
+ try {
36
+ const answer = prompt.question("Customer license key: ");
37
+ muted = true;
38
+ const value = (await answer).trim();
39
+ process.stdout.write("\n");
40
+ if (!value)
41
+ throw new Error("A customer license key is required.");
42
+ return value;
43
+ }
44
+ finally {
45
+ prompt.close();
46
+ }
47
+ }
48
+ async function activate() {
49
+ const licenseKey = await licenseCredential();
50
+ const developerEmail = argument("--developer") ?? process.env['ENDOUI_DEVELOPER_EMAIL'];
51
+ if (!developerEmail) {
52
+ throw new Error("Activation requires --developer.");
53
+ }
54
+ const normalizedEmail = developerEmail.trim().toLowerCase();
55
+ const version = resolveEndoUiVersion();
56
+ const major = packageMajor(version);
57
+ const lease = await activateDeveloper(licenseKey, normalizedEmail, version);
58
+ verifyLease(lease, version);
59
+ await writeLease(major, lease);
60
+ console.log(`EndoUI ${major}.x activated for ${normalizedEmail}.`);
61
+ }
62
+ async function activateBuild() {
63
+ const licenseKey = process.env['ENDOUI_LICENSE_KEY'];
64
+ if (!licenseKey)
65
+ throw new Error("CI activation requires ENDOUI_LICENSE_KEY.");
66
+ const version = resolveEndoUiVersion();
67
+ const major = packageMajor(version);
68
+ const lease = await activateCi(licenseKey, version);
69
+ verifyLease(lease, version);
70
+ await writeLease(major, lease);
71
+ console.log(`EndoUI ${version} CI authorization activated.`);
72
+ }
73
+ async function check() {
74
+ const version = resolveEndoUiVersion();
75
+ const major = packageMajor(version);
76
+ const lease = verifyLease(await readLease(major), version);
77
+ const refreshNotice = Math.floor(Date.now() / 1000) >= lease.refreshAfter
78
+ ? " Refresh activation when connectivity is available."
79
+ : "";
80
+ console.log(`EndoUI ${version} license verified.${refreshNotice}`);
81
+ }
82
+ async function main() {
83
+ switch (process.argv[2]) {
84
+ case "activate":
85
+ await activate();
86
+ return;
87
+ case "ci-activate":
88
+ await activateBuild();
89
+ return;
90
+ case "verify":
91
+ await check();
92
+ return;
93
+ default:
94
+ console.log("Usage: endoui-license <activate|ci-activate|verify> " +
95
+ "[--developer <email>]");
96
+ }
97
+ }
98
+ main().catch((error) => {
99
+ console.error(error instanceof Error ? error.message : "EndoUI licensing failed.");
100
+ process.exitCode = 1;
101
+ });
package/bin/lease.js ADDED
@@ -0,0 +1,36 @@
1
+ import { createPublicKey, verify } from "node:crypto";
2
+ import { ENDOUI_LEASE_KEY_ID, ENDOUI_LEASE_PUBLIC_KEY } from "./public-key.js";
3
+ function json(value) { try {
4
+ return JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
5
+ }
6
+ catch {
7
+ throw new Error("The cached EndoUI authorization is malformed.");
8
+ } }
9
+ export function verifyLease(token, packageVersion, now = Date.now(), trust = {
10
+ publicKey: ENDOUI_LEASE_PUBLIC_KEY,
11
+ keyId: ENDOUI_LEASE_KEY_ID,
12
+ issuer: "https://license.ecapsoftware.com"
13
+ }) {
14
+ if (!trust.publicKey)
15
+ throw new Error("The EndoUI verification key has not been configured for publication.");
16
+ const parts = token.split(".");
17
+ if (parts.length !== 3 || !parts[0] || !parts[1] || !parts[2])
18
+ throw new Error("The cached EndoUI authorization is malformed.");
19
+ const header = json(parts[0]);
20
+ if (header.alg !== "EdDSA" || header.typ !== "JWT" || header.kid !== trust.keyId)
21
+ throw new Error("The authorization uses an unsupported signature.");
22
+ if (!verify(null, Buffer.from(`${parts[0]}.${parts[1]}`, "ascii"), createPublicKey(trust.publicKey), Buffer.from(parts[2], "base64url")))
23
+ throw new Error("The authorization signature is invalid.");
24
+ const lease = json(parts[1]);
25
+ const seconds = Math.floor(now / 1000);
26
+ const major = Number(packageVersion.split(".", 1)[0]);
27
+ if (lease.iss !== trust.issuer || lease.aud !== "@endo-ui/license" || lease.product !== "endoui" || lease.package !== "@endo-ui/core" || lease.majorVersion !== major || lease.entitlement !== `endoui-v${major}`)
28
+ throw new Error("The authorization does not cover this EndoUI package.");
29
+ if (!Number.isSafeInteger(lease.nbf) || !Number.isSafeInteger(lease.exp))
30
+ throw new Error("The authorization has invalid timestamps.");
31
+ if (seconds < lease.nbf)
32
+ throw new Error("The authorization is not active yet. Check the system clock.");
33
+ if (seconds >= lease.exp)
34
+ throw new Error("The authorization has expired. Activate again while online.");
35
+ return lease;
36
+ }
@@ -0,0 +1,9 @@
1
+ import { createRequire } from "node:module";
2
+ import path from "node:path";
3
+ export function resolveEndoUiVersion(cwd = process.cwd()) { const require = createRequire(path.join(cwd, "package.json")); let file; try {
4
+ file = require.resolve("@endo-ui/core/package.json");
5
+ }
6
+ catch {
7
+ throw new Error("Unable to find @endo-ui/core from the current project.");
8
+ } const value = require(file); if (value.name !== "@endo-ui/core" || typeof value.version !== "string")
9
+ throw new Error("@endo-ui/core has invalid package metadata."); return value.version; }
@@ -0,0 +1,5 @@
1
+ // ECAP's public Ed25519 trust root. The matching private key remains on the VPS.
2
+ export const ENDOUI_LEASE_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
3
+ MCowBQYDK2VwAyEAu6C5H6wO9CFNj9QUF2AQH9xCcNmxQVzZs5rNrL4uWtU=
4
+ -----END PUBLIC KEY-----`;
5
+ export const ENDOUI_LEASE_KEY_ID = "endoui-lease-v1";
@@ -0,0 +1,31 @@
1
+ import { SchematicsException } from "@angular-devkit/schematics";
2
+ export default function ngAdd() {
3
+ return (tree) => {
4
+ const workspaceFile = tree.get("angular.json");
5
+ if (!workspaceFile) {
6
+ throw new SchematicsException("This project does not contain angular.json.");
7
+ }
8
+ const workspace = JSON.parse(workspaceFile.content.toString("utf8"));
9
+ let configured = false;
10
+ for (const project of Object.values(workspace.projects ?? {})) {
11
+ if (project.projectType !== "application")
12
+ continue;
13
+ const targets = project.architect ?? project.targets;
14
+ if (!targets)
15
+ continue;
16
+ if (targets['build']?.builder === "@angular/build:application") {
17
+ targets['build'].builder = "@endo-ui/license:application";
18
+ configured = true;
19
+ }
20
+ if (targets['serve']?.builder === "@angular/build:dev-server") {
21
+ targets['serve'].builder = "@endo-ui/license:dev-server";
22
+ configured = true;
23
+ }
24
+ }
25
+ if (!configured) {
26
+ throw new SchematicsException("No Angular 22 application build or serve targets were found to configure.");
27
+ }
28
+ tree.overwrite("angular.json", `${JSON.stringify(workspace, null, 2)}\n`);
29
+ return tree;
30
+ };
31
+ }
package/bin/storage.js ADDED
@@ -0,0 +1,14 @@
1
+ import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ function target(major) { const override = process.env['ENDOUI_LICENSE_CACHE']?.trim(); return override ? path.resolve(override) : path.join(os.homedir(), ".endoui", `endoui-v${major}.jwt`); }
5
+ export async function readLease(major) { try {
6
+ return (await readFile(target(major), "utf8")).trim();
7
+ }
8
+ catch (error) {
9
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
10
+ throw new Error("EndoUI is not activated. Run `endoui-license activate`.");
11
+ throw error;
12
+ } }
13
+ export async function writeLease(major, lease) { const file = target(major); await mkdir(path.dirname(file), { recursive: true, mode: 0o700 }); await writeFile(file, `${lease}\n`, { encoding: "utf8", mode: 0o600 }); if (process.platform !== "win32")
14
+ await chmod(file, 0o600); }
package/builders.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/angular-builders.json",
3
+ "builders": {
4
+ "application": {
5
+ "implementation": "./bin/builders/application.js",
6
+ "schema": "./schemas/application.json",
7
+ "description": "Verify EndoUI authorization and build an Angular application."
8
+ },
9
+ "dev-server": {
10
+ "implementation": "./bin/builders/dev-server.js",
11
+ "schema": "./schemas/dev-server.json",
12
+ "description": "Verify EndoUI authorization and serve an Angular application."
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/schematics.json",
3
+ "schematics": {
4
+ "ng-add": {
5
+ "description": "Configure Angular build and serve targets to verify EndoUI licensing.",
6
+ "factory": "./bin/schematics/ng-add/index.js"
7
+ }
8
+ }
9
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@endo-ui/license",
3
+ "version": "1.0.0",
4
+ "description": "Developer and CI license activation for EndoUI.",
5
+ "license": "SEE LICENSE IN LICENSE.md",
6
+ "publishConfig": {
7
+ "access": "restricted"
8
+ },
9
+ "type": "module",
10
+ "builders": "./builders.json",
11
+ "schematics": "./collection.json",
12
+ "bin": {
13
+ "endoui-license": "./bin/cli.js"
14
+ },
15
+ "files": [
16
+ "bin",
17
+ "builders.json",
18
+ "collection.json",
19
+ "schemas",
20
+ "LICENSE.md",
21
+ "README.md"
22
+ ],
23
+ "scripts": {
24
+ "prepack": "tsc -p tsconfig.json"
25
+ },
26
+ "peerDependencies": {
27
+ "@angular-devkit/architect": "^0.2200.0",
28
+ "@angular-devkit/schematics": "^22.0.0",
29
+ "@angular/build": "^22.0.0"
30
+ },
31
+ "engines": {
32
+ "node": "^22.22.3 || ^24.15.0 || ^26.0.0"
33
+ }
34
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "type": "object",
4
+ "additionalProperties": true
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "type": "object",
4
+ "additionalProperties": true
5
+ }