@uapkg/cli 1.1.10 → 1.3.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.
Files changed (165) hide show
  1. package/dist/app/CompositionRoot.d.ts +6 -0
  2. package/dist/app/CompositionRoot.d.ts.map +1 -1
  3. package/dist/app/CompositionRoot.js +16 -0
  4. package/dist/app/CompositionRoot.js.map +1 -1
  5. package/dist/app/UAPKGApplication.d.ts.map +1 -1
  6. package/dist/app/UAPKGApplication.js +62 -2
  7. package/dist/app/UAPKGApplication.js.map +1 -1
  8. package/dist/build/BuildMetadata.d.ts +12 -0
  9. package/dist/build/BuildMetadata.d.ts.map +1 -0
  10. package/dist/build/BuildMetadata.js +6 -0
  11. package/dist/cli/UAPKGCommandLine.d.ts +98 -3
  12. package/dist/cli/UAPKGCommandLine.d.ts.map +1 -1
  13. package/dist/cli/UAPKGCommandLine.js +69 -0
  14. package/dist/cli/UAPKGCommandLine.js.map +1 -1
  15. package/dist/cli/parsing/UAPKGCommandLineParser.d.ts.map +1 -1
  16. package/dist/cli/parsing/UAPKGCommandLineParser.js +8 -1
  17. package/dist/cli/parsing/UAPKGCommandLineParser.js.map +1 -1
  18. package/dist/cli/parsing/UAPKGParserRegistry.d.ts.map +1 -1
  19. package/dist/cli/parsing/UAPKGParserRegistry.js +12 -0
  20. package/dist/cli/parsing/UAPKGParserRegistry.js.map +1 -1
  21. package/dist/cli/parsing/modules/LifecycleCommandModule.d.ts +11 -0
  22. package/dist/cli/parsing/modules/LifecycleCommandModule.d.ts.map +1 -0
  23. package/dist/cli/parsing/modules/LifecycleCommandModule.js +56 -0
  24. package/dist/cli/parsing/modules/LifecycleCommandModule.js.map +1 -0
  25. package/dist/cli/parsing/modules/LoginCommandModule.d.ts +7 -0
  26. package/dist/cli/parsing/modules/LoginCommandModule.d.ts.map +1 -0
  27. package/dist/cli/parsing/modules/LoginCommandModule.js +34 -0
  28. package/dist/cli/parsing/modules/LoginCommandModule.js.map +1 -0
  29. package/dist/cli/parsing/modules/LogoutCommandModule.d.ts +7 -0
  30. package/dist/cli/parsing/modules/LogoutCommandModule.d.ts.map +1 -0
  31. package/dist/cli/parsing/modules/LogoutCommandModule.js +29 -0
  32. package/dist/cli/parsing/modules/LogoutCommandModule.js.map +1 -0
  33. package/dist/cli/parsing/modules/PublishCommandModule.d.ts +7 -0
  34. package/dist/cli/parsing/modules/PublishCommandModule.d.ts.map +1 -0
  35. package/dist/cli/parsing/modules/PublishCommandModule.js +50 -0
  36. package/dist/cli/parsing/modules/PublishCommandModule.js.map +1 -0
  37. package/dist/cli/parsing/modules/RegistryCommandModule.d.ts.map +1 -1
  38. package/dist/cli/parsing/modules/RegistryCommandModule.js +31 -2
  39. package/dist/cli/parsing/modules/RegistryCommandModule.js.map +1 -1
  40. package/dist/cli/parsing/modules/RequestsCommandModule.d.ts +7 -0
  41. package/dist/cli/parsing/modules/RequestsCommandModule.d.ts.map +1 -0
  42. package/dist/cli/parsing/modules/RequestsCommandModule.js +63 -0
  43. package/dist/cli/parsing/modules/RequestsCommandModule.js.map +1 -0
  44. package/dist/cli/parsing/modules/WhoamiCommandModule.d.ts +7 -0
  45. package/dist/cli/parsing/modules/WhoamiCommandModule.d.ts.map +1 -0
  46. package/dist/cli/parsing/modules/WhoamiCommandModule.js +29 -0
  47. package/dist/cli/parsing/modules/WhoamiCommandModule.js.map +1 -0
  48. package/dist/cli-bootstrap.d.ts +2 -0
  49. package/dist/cli-bootstrap.d.ts.map +1 -0
  50. package/dist/cli-bootstrap.js +17 -0
  51. package/dist/cli-bootstrap.js.map +1 -0
  52. package/dist/cli.js +24 -17
  53. package/dist/commands/InstallCommand.d.ts.map +1 -1
  54. package/dist/commands/InstallCommand.js +21 -6
  55. package/dist/commands/InstallCommand.js.map +1 -1
  56. package/dist/commands/LoginCommand.d.ts +17 -0
  57. package/dist/commands/LoginCommand.d.ts.map +1 -0
  58. package/dist/commands/LoginCommand.js +73 -0
  59. package/dist/commands/LoginCommand.js.map +1 -0
  60. package/dist/commands/LogoutCommand.d.ts +15 -0
  61. package/dist/commands/LogoutCommand.d.ts.map +1 -0
  62. package/dist/commands/LogoutCommand.js +38 -0
  63. package/dist/commands/LogoutCommand.js.map +1 -0
  64. package/dist/commands/PackageLifecycleCommand.d.ts +28 -0
  65. package/dist/commands/PackageLifecycleCommand.d.ts.map +1 -0
  66. package/dist/commands/PackageLifecycleCommand.js +143 -0
  67. package/dist/commands/PackageLifecycleCommand.js.map +1 -0
  68. package/dist/commands/PostinstallCandidateBuilder.d.ts +1 -1
  69. package/dist/commands/PostinstallCandidateBuilder.d.ts.map +1 -1
  70. package/dist/commands/PostinstallCandidateBuilder.js +4 -1
  71. package/dist/commands/PostinstallCandidateBuilder.js.map +1 -1
  72. package/dist/commands/PublishCommand.d.ts +32 -0
  73. package/dist/commands/PublishCommand.d.ts.map +1 -0
  74. package/dist/commands/PublishCommand.js +270 -0
  75. package/dist/commands/PublishCommand.js.map +1 -0
  76. package/dist/commands/RegistryCommand.d.ts +13 -3
  77. package/dist/commands/RegistryCommand.d.ts.map +1 -1
  78. package/dist/commands/RegistryCommand.js +115 -11
  79. package/dist/commands/RegistryCommand.js.map +1 -1
  80. package/dist/commands/RequestsCommand.d.ts +21 -0
  81. package/dist/commands/RequestsCommand.d.ts.map +1 -0
  82. package/dist/commands/RequestsCommand.js +98 -0
  83. package/dist/commands/RequestsCommand.js.map +1 -0
  84. package/dist/commands/WhoamiCommand.d.ts +32 -0
  85. package/dist/commands/WhoamiCommand.d.ts.map +1 -0
  86. package/dist/commands/WhoamiCommand.js +75 -0
  87. package/dist/commands/WhoamiCommand.js.map +1 -0
  88. package/dist/commands/add/DependencyAddResolver.d.ts.map +1 -1
  89. package/dist/commands/add/DependencyAddResolver.js +4 -2
  90. package/dist/commands/add/DependencyAddResolver.js.map +1 -1
  91. package/dist/control-plane/AccountManager.d.ts +110 -0
  92. package/dist/control-plane/AccountManager.d.ts.map +1 -0
  93. package/dist/control-plane/AccountManager.js +1014 -0
  94. package/dist/control-plane/AccountManager.js.map +1 -0
  95. package/dist/control-plane/ArtifactObserver.d.ts +24 -0
  96. package/dist/control-plane/ArtifactObserver.d.ts.map +1 -0
  97. package/dist/control-plane/ArtifactObserver.js +63 -0
  98. package/dist/control-plane/ArtifactObserver.js.map +1 -0
  99. package/dist/control-plane/AuthMetadataStore.d.ts +15 -0
  100. package/dist/control-plane/AuthMetadataStore.d.ts.map +1 -0
  101. package/dist/control-plane/AuthMetadataStore.js +116 -0
  102. package/dist/control-plane/AuthMetadataStore.js.map +1 -0
  103. package/dist/control-plane/AuthStoragePaths.d.ts +11 -0
  104. package/dist/control-plane/AuthStoragePaths.d.ts.map +1 -0
  105. package/dist/control-plane/AuthStoragePaths.js +17 -0
  106. package/dist/control-plane/AuthStoragePaths.js.map +1 -0
  107. package/dist/control-plane/AuthenticationSelector.d.ts +21 -0
  108. package/dist/control-plane/AuthenticationSelector.d.ts.map +1 -0
  109. package/dist/control-plane/AuthenticationSelector.js +64 -0
  110. package/dist/control-plane/AuthenticationSelector.js.map +1 -0
  111. package/dist/control-plane/ControlPlaneClient.d.ts +32 -0
  112. package/dist/control-plane/ControlPlaneClient.d.ts.map +1 -0
  113. package/dist/control-plane/ControlPlaneClient.js +280 -0
  114. package/dist/control-plane/ControlPlaneClient.js.map +1 -0
  115. package/dist/control-plane/ControlPlaneEndpoints.d.ts +13 -0
  116. package/dist/control-plane/ControlPlaneEndpoints.d.ts.map +1 -0
  117. package/dist/control-plane/ControlPlaneEndpoints.js +19 -0
  118. package/dist/control-plane/ControlPlaneEndpoints.js.map +1 -0
  119. package/dist/control-plane/ControlPlaneTypes.d.ts +168 -0
  120. package/dist/control-plane/ControlPlaneTypes.d.ts.map +1 -0
  121. package/dist/control-plane/ControlPlaneTypes.js +93 -0
  122. package/dist/control-plane/ControlPlaneTypes.js.map +1 -0
  123. package/dist/control-plane/CredentialStore.d.ts +28 -0
  124. package/dist/control-plane/CredentialStore.d.ts.map +1 -0
  125. package/dist/control-plane/CredentialStore.js +87 -0
  126. package/dist/control-plane/CredentialStore.js.map +1 -0
  127. package/dist/control-plane/DPoPKeyStore.d.ts +11 -0
  128. package/dist/control-plane/DPoPKeyStore.d.ts.map +1 -0
  129. package/dist/control-plane/DPoPKeyStore.js +54 -0
  130. package/dist/control-plane/DPoPKeyStore.js.map +1 -0
  131. package/dist/control-plane/GitHubActionsOidcCredentialProvider.d.ts +6 -0
  132. package/dist/control-plane/GitHubActionsOidcCredentialProvider.d.ts.map +1 -0
  133. package/dist/control-plane/GitHubActionsOidcCredentialProvider.js +67 -0
  134. package/dist/control-plane/GitHubActionsOidcCredentialProvider.js.map +1 -0
  135. package/dist/control-plane/PublishIdempotencyStore.d.ts +18 -0
  136. package/dist/control-plane/PublishIdempotencyStore.d.ts.map +1 -0
  137. package/dist/control-plane/PublishIdempotencyStore.js +71 -0
  138. package/dist/control-plane/PublishIdempotencyStore.js.map +1 -0
  139. package/dist/control-plane/RegistryGrantLock.d.ts +35 -0
  140. package/dist/control-plane/RegistryGrantLock.d.ts.map +1 -0
  141. package/dist/control-plane/RegistryGrantLock.js +199 -0
  142. package/dist/control-plane/RegistryGrantLock.js.map +1 -0
  143. package/dist/control-plane/RegistryTrustResolver.d.ts +17 -0
  144. package/dist/control-plane/RegistryTrustResolver.d.ts.map +1 -0
  145. package/dist/control-plane/RegistryTrustResolver.js +140 -0
  146. package/dist/control-plane/RegistryTrustResolver.js.map +1 -0
  147. package/dist/index.d.ts +16 -3
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +16 -2
  150. package/dist/index.js.map +1 -1
  151. package/dist/postinstall/markers/MarkerIntegrityValidator.d.ts +1 -1
  152. package/dist/prompts/InkPromptService.d.ts +1 -0
  153. package/dist/prompts/InkPromptService.d.ts.map +1 -1
  154. package/dist/prompts/InkPromptService.js +20 -0
  155. package/dist/prompts/InkPromptService.js.map +1 -1
  156. package/dist/prompts/PromptService.d.ts +2 -0
  157. package/dist/prompts/PromptService.d.ts.map +1 -1
  158. package/dist/reporting/JsonReporter.d.ts +2 -0
  159. package/dist/reporting/JsonReporter.d.ts.map +1 -1
  160. package/dist/reporting/JsonReporter.js +6 -0
  161. package/dist/reporting/JsonReporter.js.map +1 -1
  162. package/package.json +21 -15
  163. package/dist/cli.d.ts +0 -3
  164. package/dist/cli.d.ts.map +0 -1
  165. package/dist/cli.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CredentialStore.d.ts","sourceRoot":"","sources":["../../src/control-plane/CredentialStore.ts"],"names":[],"mappings":"AAEA,UAAU,YAAY;IACpB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,WAAW,IAAI,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,IAAI,OAAO,CAAC;CAC7B;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,KAAK,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,YAAY,CAAC;CAChE;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;AAEzD;;;GAGG;AACH,qBAAa,eAAe;IAIxB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,MAAM,CAAC,CAAgB;gBAGZ,WAAW,GAAE,aAA+E,EAC5F,OAAO,SAAc;IAG3B,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBhC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAYnD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWpD,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa9C,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAO/G,OAAO,CAAC,KAAK;YAOC,YAAY;CAG3B"}
@@ -0,0 +1,87 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ /**
3
+ * Protected secret storage. The native module is imported only when a
4
+ * control-plane command needs it, so install/search/update remain portable.
5
+ */
6
+ export class CredentialStore {
7
+ loadKeyring;
8
+ service;
9
+ module;
10
+ constructor(loadKeyring = async () => (await import('@napi-rs/keyring')), service = 'uapkg.cli') {
11
+ this.loadKeyring = loadKeyring;
12
+ this.service = service;
13
+ }
14
+ async assertAvailable() {
15
+ const reference = `availability:${randomUUID()}`;
16
+ try {
17
+ await this.set(reference, reference);
18
+ const roundTrip = await this.get(reference);
19
+ if (roundTrip !== reference) {
20
+ throw new Error('The operating-system credential store failed a round-trip check.');
21
+ }
22
+ }
23
+ catch (error) {
24
+ throw new Error('Secure operating-system credential storage is unavailable. UAPKG will not save login secrets in plaintext.', { cause: error });
25
+ }
26
+ finally {
27
+ await this.delete(reference).catch(() => undefined);
28
+ }
29
+ }
30
+ async get(reference) {
31
+ await this.ensureModule();
32
+ try {
33
+ return this.entry(reference).getPassword() ?? undefined;
34
+ }
35
+ catch (error) {
36
+ if (isMissingCredentialError(error))
37
+ return undefined;
38
+ throw new Error('Unable to read a UAPKG credential from protected operating-system storage.', {
39
+ cause: error,
40
+ });
41
+ }
42
+ }
43
+ async set(reference, value) {
44
+ await this.ensureModule();
45
+ try {
46
+ this.entry(reference).setPassword(value);
47
+ }
48
+ catch (error) {
49
+ throw new Error('Unable to save a UAPKG credential in protected operating-system storage.', {
50
+ cause: error,
51
+ });
52
+ }
53
+ }
54
+ async delete(reference) {
55
+ await this.ensureModule();
56
+ try {
57
+ this.entry(reference).deleteCredential();
58
+ }
59
+ catch (error) {
60
+ if (!isMissingCredentialError(error)) {
61
+ throw new Error('Unable to remove a UAPKG credential from protected operating-system storage.', {
62
+ cause: error,
63
+ });
64
+ }
65
+ }
66
+ }
67
+ createReference(kind, issuer, registryId, grantId) {
68
+ const digest = createHash('sha256')
69
+ .update(`${kind}\0${issuer.replace(/\/+$/, '')}\0${registryId.toLowerCase()}\0${grantId}`)
70
+ .digest('hex');
71
+ return `${kind}:${digest}`;
72
+ }
73
+ entry(reference) {
74
+ if (!this.module) {
75
+ throw new Error('CredentialStore has not loaded the native keyring yet.');
76
+ }
77
+ return new this.module.Entry(this.service, reference);
78
+ }
79
+ async ensureModule() {
80
+ this.module ??= await this.loadKeyring();
81
+ }
82
+ }
83
+ function isMissingCredentialError(error) {
84
+ const message = error instanceof Error ? error.message : String(error);
85
+ return /no\s*entry|not\s*found|missing/i.test(message);
86
+ }
87
+ //# sourceMappingURL=CredentialStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CredentialStore.js","sourceRoot":"","sources":["../../src/control-plane/CredentialStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type * as oauth from 'oauth4webapi';
2
+ import type { CredentialStore } from './CredentialStore.js';
3
+ export declare class DPoPKeyStore {
4
+ private readonly credentials;
5
+ constructor(credentials: CredentialStore);
6
+ generate(): Promise<oauth.CryptoKeyPair>;
7
+ save(reference: string, pair: oauth.CryptoKeyPair): Promise<void>;
8
+ load(reference: string): Promise<oauth.CryptoKeyPair | undefined>;
9
+ delete(reference: string): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=DPoPKeyStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DPoPKeyStore.d.ts","sourceRoot":"","sources":["../../src/control-plane/DPoPKeyStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAQ5D,qBAAa,YAAY;IACJ,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,eAAe;IAEnD,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;IAKxC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAajE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,SAAS,CAAC;IA4BjE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGtD"}
@@ -0,0 +1,54 @@
1
+ import { webcrypto } from 'node:crypto';
2
+ export class DPoPKeyStore {
3
+ credentials;
4
+ constructor(credentials) {
5
+ this.credentials = credentials;
6
+ }
7
+ async generate() {
8
+ const { generateKeyPair } = await import('oauth4webapi');
9
+ return generateKeyPair('ES256', { extractable: true });
10
+ }
11
+ async save(reference, pair) {
12
+ const [publicKey, privateKey] = await Promise.all([
13
+ webcrypto.subtle.exportKey('jwk', pair.publicKey),
14
+ webcrypto.subtle.exportKey('jwk', pair.privateKey),
15
+ ]);
16
+ const serialized = {
17
+ algorithm: 'ES256',
18
+ publicKey,
19
+ privateKey,
20
+ };
21
+ await this.credentials.set(reference, JSON.stringify(serialized));
22
+ }
23
+ async load(reference) {
24
+ const raw = await this.credentials.get(reference);
25
+ if (!raw)
26
+ return undefined;
27
+ let saved;
28
+ try {
29
+ saved = JSON.parse(raw);
30
+ }
31
+ catch (error) {
32
+ throw new Error('The saved UAPKG DPoP key is not valid JSON.', { cause: error });
33
+ }
34
+ if (saved.algorithm !== 'ES256' || !saved.publicKey || !saved.privateKey) {
35
+ throw new Error('The saved UAPKG DPoP key has an unsupported format.');
36
+ }
37
+ const algorithm = { name: 'ECDSA', namedCurve: 'P-256' };
38
+ const [publicKey, privateKey] = await Promise.all([
39
+ webcrypto.subtle.importKey('jwk', saved.publicKey, algorithm, true, ['verify']),
40
+ webcrypto.subtle.importKey('jwk', saved.privateKey, algorithm, true, ['sign']),
41
+ ]);
42
+ const challenge = webcrypto.getRandomValues(new Uint8Array(32));
43
+ const signature = await webcrypto.subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, privateKey, challenge);
44
+ const matches = await webcrypto.subtle.verify({ name: 'ECDSA', hash: 'SHA-256' }, publicKey, signature, challenge);
45
+ if (!matches) {
46
+ throw new Error('The saved UAPKG DPoP public and private keys do not match.');
47
+ }
48
+ return { publicKey, privateKey };
49
+ }
50
+ async delete(reference) {
51
+ await this.credentials.delete(reference);
52
+ }
53
+ }
54
+ //# sourceMappingURL=DPoPKeyStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DPoPKeyStore.js","sourceRoot":"","sources":["../../src/control-plane/DPoPKeyStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type RegistryTrust } from './ControlPlaneTypes.js';
2
+ export declare class GitHubActionsOidcCredentialProvider {
3
+ isAvailable(): boolean;
4
+ exchange(trust: RegistryTrust): Promise<string>;
5
+ }
6
+ //# sourceMappingURL=GitHubActionsOidcCredentialProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubActionsOidcCredentialProvider.d.ts","sourceRoot":"","sources":["../../src/control-plane/GitHubActionsOidcCredentialProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,wBAAwB,CAAC;AAShC,qBAAa,mCAAmC;IACvC,WAAW,IAAI,OAAO;IAQhB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;CAkD7D"}
@@ -0,0 +1,67 @@
1
+ import { z } from 'zod';
2
+ import { ControlPlaneError, UAPKG_CONTROL_PLANE_API, UAPKG_GITHUB_OIDC_AUDIENCE, } from './ControlPlaneTypes.js';
3
+ const githubResponseSchema = z.object({ value: z.string().min(1) });
4
+ const exchangeResponseSchema = z.object({
5
+ ok: z.literal(true),
6
+ token: z.string().min(1),
7
+ expiresAt: z.number().int().positive(),
8
+ });
9
+ export class GitHubActionsOidcCredentialProvider {
10
+ isAvailable() {
11
+ return Boolean(process.env.GITHUB_ACTIONS === 'true' ||
12
+ process.env.ACTIONS_ID_TOKEN_REQUEST_URL ||
13
+ process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN);
14
+ }
15
+ async exchange(trust) {
16
+ if (trust.apiBaseUrl !== UAPKG_CONTROL_PLANE_API) {
17
+ throw new Error(`UAPKG v1 OIDC exchange is pinned to ${UAPKG_CONTROL_PLANE_API}.`);
18
+ }
19
+ const requestUrl = process.env.ACTIONS_ID_TOKEN_REQUEST_URL;
20
+ const requestToken = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN;
21
+ if (!this.isAvailable() || !requestUrl || !requestToken) {
22
+ throw new Error('GitHub Actions OIDC was selected but its identity-token endpoint is unavailable. The workflow must grant `id-token: write`.');
23
+ }
24
+ const url = new URL(requestUrl);
25
+ if (url.protocol !== 'https:' || !url.hostname.endsWith('.actions.githubusercontent.com')) {
26
+ throw new Error('GitHub Actions supplied an unexpected OIDC token endpoint.');
27
+ }
28
+ url.searchParams.set('audience', UAPKG_GITHUB_OIDC_AUDIENCE);
29
+ const githubResponse = await fetch(url, {
30
+ headers: { authorization: `Bearer ${requestToken}` },
31
+ });
32
+ const githubValue = githubResponseSchema.safeParse(await safeJson(githubResponse));
33
+ if (!githubResponse.ok || !githubValue.success) {
34
+ throw new Error(`GitHub Actions did not issue an OIDC identity token (HTTP ${githubResponse.status}).`);
35
+ }
36
+ const exchangeResponse = await fetch(new URL('/v1/github-user-app/oidc/github-actions/exchange', trust.apiBaseUrl), {
37
+ method: 'POST',
38
+ headers: { 'content-type': 'application/json' },
39
+ body: JSON.stringify({
40
+ provider: 'github_actions',
41
+ audience: UAPKG_GITHUB_OIDC_AUDIENCE,
42
+ idToken: githubValue.data.value,
43
+ }),
44
+ });
45
+ const exchangeValue = await safeJson(exchangeResponse);
46
+ if (!exchangeResponse.ok) {
47
+ const error = z.object({ error: z.object({ code: z.string(), message: z.string() }) }).safeParse(exchangeValue);
48
+ if (error.success) {
49
+ throw new ControlPlaneError(error.data.error.code, error.data.error.message, exchangeResponse.status);
50
+ }
51
+ throw new Error(`UAPKG rejected the GitHub Actions identity (HTTP ${exchangeResponse.status}).`);
52
+ }
53
+ const parsed = exchangeResponseSchema.safeParse(exchangeValue);
54
+ if (!parsed.success)
55
+ throw new Error('The UAPKG OIDC exchange response was invalid.');
56
+ return parsed.data.token;
57
+ }
58
+ }
59
+ async function safeJson(response) {
60
+ try {
61
+ return (await response.json());
62
+ }
63
+ catch {
64
+ return {};
65
+ }
66
+ }
67
+ //# sourceMappingURL=GitHubActionsOidcCredentialProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubActionsOidcCredentialProvider.js","sourceRoot":"","sources":["../../src/control-plane/GitHubActionsOidcCredentialProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Persisted idempotency keys for logical registry-operation submissions.
3
+ * One logical submission (operation + registry + payload) keeps one key
4
+ * across retries, so a re-run after a network fault or crash replays the
5
+ * original request instead of creating a duplicate. Keys are cleared once
6
+ * the request reaches a terminal state.
7
+ */
8
+ export declare class PublishIdempotencyStore {
9
+ private readonly filePath;
10
+ constructor(filePath?: string);
11
+ /** Stable digest identifying one logical submission. */
12
+ static submissionDigest(operation: string, submission: unknown): string;
13
+ getOrCreate(digest: string, newKey: () => string, now?: number): string;
14
+ clear(digest: string, now?: number): void;
15
+ private read;
16
+ private write;
17
+ }
18
+ //# sourceMappingURL=PublishIdempotencyStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PublishIdempotencyStore.d.ts","sourceRoot":"","sources":["../../src/control-plane/PublishIdempotencyStore.ts"],"names":[],"mappings":"AAkBA;;;;;;GAMG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEf,QAAQ,CAAC,EAAE,MAAM;IAIpC,wDAAwD;WAC1C,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM;IAIvE,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,GAAG,SAAa,GAAG,MAAM;IAY3E,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI;IAQpD,OAAO,CAAC,IAAI;IAyBZ,OAAO,CAAC,KAAK;CAId"}
@@ -0,0 +1,71 @@
1
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { resolveActiveUapkgProfileRoot } from '@uapkg/common';
4
+ import { sha256OfCanonicalJson } from '@uapkg/package-claims';
5
+ const STORE_FILE_NAME = 'publish-idempotency.json';
6
+ const MAX_ENTRY_AGE_MS = 7 * 24 * 60 * 60 * 1000;
7
+ /**
8
+ * Persisted idempotency keys for logical registry-operation submissions.
9
+ * One logical submission (operation + registry + payload) keeps one key
10
+ * across retries, so a re-run after a network fault or crash replays the
11
+ * original request instead of creating a duplicate. Keys are cleared once
12
+ * the request reaches a terminal state.
13
+ */
14
+ export class PublishIdempotencyStore {
15
+ filePath;
16
+ constructor(filePath) {
17
+ this.filePath = filePath ?? join(resolveActiveUapkgProfileRoot(), STORE_FILE_NAME);
18
+ }
19
+ /** Stable digest identifying one logical submission. */
20
+ static submissionDigest(operation, submission) {
21
+ return sha256OfCanonicalJson({ operation, submission });
22
+ }
23
+ getOrCreate(digest, newKey, now = Date.now()) {
24
+ const store = this.read(now);
25
+ const existing = store.entries[digest];
26
+ if (existing)
27
+ return existing.key;
28
+ const key = newKey();
29
+ this.write({
30
+ schemaVersion: 1,
31
+ entries: { ...store.entries, [digest]: { key, createdAt: now } },
32
+ });
33
+ return key;
34
+ }
35
+ clear(digest, now = Date.now()) {
36
+ const store = this.read(now);
37
+ if (!(digest in store.entries))
38
+ return;
39
+ const entries = { ...store.entries };
40
+ delete entries[digest];
41
+ this.write({ schemaVersion: 1, entries });
42
+ }
43
+ read(now) {
44
+ let parsed;
45
+ try {
46
+ const raw = readFileSync(this.filePath, 'utf8');
47
+ const candidate = JSON.parse(raw);
48
+ if (candidate.schemaVersion === 1 && candidate.entries && typeof candidate.entries === 'object') {
49
+ parsed = { schemaVersion: 1, entries: candidate.entries };
50
+ }
51
+ }
52
+ catch {
53
+ // Missing or corrupt store starts fresh; keys are best-effort retry aids.
54
+ }
55
+ const entries = {};
56
+ for (const [digest, entry] of Object.entries(parsed?.entries ?? {})) {
57
+ if (entry &&
58
+ typeof entry.key === 'string' &&
59
+ typeof entry.createdAt === 'number' &&
60
+ now - entry.createdAt <= MAX_ENTRY_AGE_MS) {
61
+ entries[digest] = entry;
62
+ }
63
+ }
64
+ return { schemaVersion: 1, entries };
65
+ }
66
+ write(store) {
67
+ mkdirSync(dirname(this.filePath), { recursive: true });
68
+ writeFileSync(this.filePath, `${JSON.stringify(store, null, 2)}\n`, 'utf8');
69
+ }
70
+ }
71
+ //# sourceMappingURL=PublishIdempotencyStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PublishIdempotencyStore.js","sourceRoot":"","sources":["../../src/control-plane/PublishIdempotencyStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export interface RegistryGrantLock {
2
+ withLock<T>(issuer: string, registryId: string, operation: () => Promise<T>): Promise<T>;
3
+ }
4
+ export interface FileRegistryGrantLockOptions {
5
+ readonly waitTimeoutMs?: number;
6
+ readonly staleAfterMs?: number;
7
+ readonly pollIntervalMs?: number;
8
+ readonly heartbeatIntervalMs?: number;
9
+ readonly now?: () => number;
10
+ readonly sleep?: (milliseconds: number) => Promise<void>;
11
+ readonly isProcessAlive?: (pid: number) => boolean;
12
+ }
13
+ /**
14
+ * Cross-process serialization for a registry grant's rotating refresh-token
15
+ * family. Lock file names contain only a SHA-256 digest of the issuer and
16
+ * registry ID; lock contents contain only an opaque owner ID, PID, and time.
17
+ */
18
+ export declare class FileRegistryGrantLock implements RegistryGrantLock {
19
+ private readonly directory;
20
+ private readonly waitTimeoutMs;
21
+ private readonly staleAfterMs;
22
+ private readonly pollIntervalMs;
23
+ private readonly heartbeatIntervalMs;
24
+ private readonly now;
25
+ private readonly sleep;
26
+ private readonly isProcessAlive;
27
+ constructor(directory: string, options?: FileRegistryGrantLockOptions);
28
+ pathFor(issuer: string, registryId: string): string;
29
+ withLock<T>(issuer: string, registryId: string, operation: () => Promise<T>): Promise<T>;
30
+ private tryAcquire;
31
+ private reclaimIfStale;
32
+ private touchIfOwned;
33
+ private releaseIfOwned;
34
+ }
35
+ //# sourceMappingURL=RegistryGrantLock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RegistryGrantLock.d.ts","sourceRoot":"","sources":["../../src/control-plane/RegistryGrantLock.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC1F;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACpD;AAED;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,iBAAiB;IAU3D,OAAO,CAAC,QAAQ,CAAC,SAAS;IAT5B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0C;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2B;gBAGvC,SAAS,EAAE,MAAM,EAClC,OAAO,GAAE,4BAAiC;IAcrC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAO7C,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;YAmCvF,UAAU;YAoBV,cAAc;YA2Cd,YAAY;YAOZ,cAAc;CAa7B"}
@@ -0,0 +1,199 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { mkdir, open, readFile, rename, stat, unlink, utimes } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ const LOCK_FILE_VERSION = 1;
5
+ const DEFAULT_WAIT_TIMEOUT_MS = 30_000;
6
+ const DEFAULT_STALE_AFTER_MS = 120_000;
7
+ const DEFAULT_POLL_INTERVAL_MS = 50;
8
+ const DEFAULT_HEARTBEAT_INTERVAL_MS = 5_000;
9
+ /**
10
+ * Cross-process serialization for a registry grant's rotating refresh-token
11
+ * family. Lock file names contain only a SHA-256 digest of the issuer and
12
+ * registry ID; lock contents contain only an opaque owner ID, PID, and time.
13
+ */
14
+ export class FileRegistryGrantLock {
15
+ directory;
16
+ waitTimeoutMs;
17
+ staleAfterMs;
18
+ pollIntervalMs;
19
+ heartbeatIntervalMs;
20
+ now;
21
+ sleep;
22
+ isProcessAlive;
23
+ constructor(directory, options = {}) {
24
+ this.directory = directory;
25
+ this.waitTimeoutMs = positiveMilliseconds(options.waitTimeoutMs, DEFAULT_WAIT_TIMEOUT_MS);
26
+ this.staleAfterMs = positiveMilliseconds(options.staleAfterMs, DEFAULT_STALE_AFTER_MS);
27
+ this.pollIntervalMs = positiveMilliseconds(options.pollIntervalMs, DEFAULT_POLL_INTERVAL_MS);
28
+ this.heartbeatIntervalMs = positiveMilliseconds(options.heartbeatIntervalMs, Math.min(DEFAULT_HEARTBEAT_INTERVAL_MS, Math.max(1, Math.floor(this.staleAfterMs / 3))));
29
+ this.now = options.now ?? Date.now;
30
+ this.sleep = options.sleep ?? delay;
31
+ this.isProcessAlive = options.isProcessAlive ?? processIsAlive;
32
+ }
33
+ pathFor(issuer, registryId) {
34
+ const digest = createHash('sha256')
35
+ .update(`${issuer.replace(/\/+$/, '')}\0${registryId.toLowerCase()}`)
36
+ .digest('hex');
37
+ return join(this.directory, `${digest}.lock`);
38
+ }
39
+ async withLock(issuer, registryId, operation) {
40
+ await mkdir(this.directory, { recursive: true, mode: 0o700 });
41
+ const lockPath = this.pathFor(issuer, registryId);
42
+ const owner = {
43
+ version: LOCK_FILE_VERSION,
44
+ ownerId: randomUUID(),
45
+ pid: process.pid,
46
+ acquiredAt: this.now(),
47
+ };
48
+ const deadline = this.now() + this.waitTimeoutMs;
49
+ while (!(await this.tryAcquire(lockPath, owner))) {
50
+ if (await this.reclaimIfStale(lockPath))
51
+ continue;
52
+ const remaining = deadline - this.now();
53
+ if (remaining <= 0) {
54
+ throw new Error('Timed out waiting for another UAPKG process to finish using the saved login for this registry.');
55
+ }
56
+ await this.sleep(Math.min(this.pollIntervalMs, remaining));
57
+ }
58
+ const heartbeat = setInterval(() => {
59
+ void this.touchIfOwned(lockPath, owner.ownerId);
60
+ }, this.heartbeatIntervalMs);
61
+ heartbeat.unref?.();
62
+ try {
63
+ return await operation();
64
+ }
65
+ finally {
66
+ clearInterval(heartbeat);
67
+ await this.releaseIfOwned(lockPath, owner.ownerId);
68
+ }
69
+ }
70
+ async tryAcquire(lockPath, owner) {
71
+ let handle;
72
+ try {
73
+ handle = await open(lockPath, 'wx', 0o600);
74
+ }
75
+ catch (error) {
76
+ if (errorCode(error) === 'EEXIST')
77
+ return false;
78
+ throw new Error('Unable to create the UAPKG registry-grant lock.', { cause: error });
79
+ }
80
+ try {
81
+ await handle.writeFile(JSON.stringify(owner), { encoding: 'utf8' });
82
+ return true;
83
+ }
84
+ catch (error) {
85
+ await unlink(lockPath).catch(() => undefined);
86
+ throw new Error('Unable to initialize the UAPKG registry-grant lock.', { cause: error });
87
+ }
88
+ finally {
89
+ await handle.close();
90
+ }
91
+ }
92
+ async reclaimIfStale(lockPath) {
93
+ let lockStat;
94
+ try {
95
+ lockStat = await stat(lockPath);
96
+ }
97
+ catch (error) {
98
+ if (errorCode(error) === 'ENOENT')
99
+ return true;
100
+ throw new Error('Unable to inspect the UAPKG registry-grant lock.', { cause: error });
101
+ }
102
+ const observedOwner = await readOwner(lockPath);
103
+ if (observedOwner) {
104
+ // A valid owner record with a definitely dead PID is safe to reclaim
105
+ // immediately. Waiting for the general stale threshold would make a
106
+ // refresh retry miss the authorization server's bounded predecessor
107
+ // grace after a process dies between rotation and local persistence.
108
+ if (this.isProcessAlive(observedOwner.pid))
109
+ return false;
110
+ }
111
+ else if (this.now() - lockStat.mtimeMs <= this.staleAfterMs) {
112
+ // A just-created lock can briefly be empty while its owner record is
113
+ // written. Malformed or unreadable ownership therefore remains subject
114
+ // to the conservative stale threshold.
115
+ return false;
116
+ }
117
+ const quarantinePath = `${lockPath}.stale-${randomUUID()}`;
118
+ try {
119
+ await rename(lockPath, quarantinePath);
120
+ }
121
+ catch (error) {
122
+ if (errorCode(error) === 'ENOENT')
123
+ return true;
124
+ throw new Error('Unable to quarantine a stale UAPKG registry-grant lock.', { cause: error });
125
+ }
126
+ const movedOwner = await readOwner(quarantinePath);
127
+ if (observedOwner && movedOwner?.ownerId !== observedOwner.ownerId) {
128
+ await rename(quarantinePath, lockPath).catch(() => undefined);
129
+ return false;
130
+ }
131
+ await unlink(quarantinePath).catch((error) => {
132
+ throw new Error('Unable to remove a stale UAPKG registry-grant lock.', { cause: error });
133
+ });
134
+ return true;
135
+ }
136
+ async touchIfOwned(lockPath, ownerId) {
137
+ const owner = await readOwner(lockPath);
138
+ if (owner?.ownerId !== ownerId)
139
+ return;
140
+ const now = new Date(this.now());
141
+ await utimes(lockPath, now, now).catch(() => undefined);
142
+ }
143
+ async releaseIfOwned(lockPath, ownerId) {
144
+ const owner = await readOwner(lockPath);
145
+ if (!owner)
146
+ return;
147
+ if (owner.ownerId !== ownerId) {
148
+ throw new Error('The UAPKG registry-grant lock changed ownership before it could be released.');
149
+ }
150
+ try {
151
+ await unlink(lockPath);
152
+ }
153
+ catch (error) {
154
+ if (errorCode(error) === 'ENOENT')
155
+ return;
156
+ throw new Error('Unable to release the UAPKG registry-grant lock.', { cause: error });
157
+ }
158
+ }
159
+ }
160
+ async function readOwner(lockPath) {
161
+ try {
162
+ const value = JSON.parse(await readFile(lockPath, 'utf8'));
163
+ if (typeof value !== 'object' ||
164
+ value === null ||
165
+ value.version !== LOCK_FILE_VERSION ||
166
+ typeof value.ownerId !== 'string' ||
167
+ !Number.isInteger(value.pid) ||
168
+ typeof value.acquiredAt !== 'number') {
169
+ return undefined;
170
+ }
171
+ return value;
172
+ }
173
+ catch {
174
+ return undefined;
175
+ }
176
+ }
177
+ function processIsAlive(pid) {
178
+ if (pid === process.pid)
179
+ return true;
180
+ try {
181
+ process.kill(pid, 0);
182
+ return true;
183
+ }
184
+ catch (error) {
185
+ return errorCode(error) !== 'ESRCH';
186
+ }
187
+ }
188
+ function positiveMilliseconds(value, fallback) {
189
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : fallback;
190
+ }
191
+ function errorCode(error) {
192
+ return typeof error === 'object' && error !== null && 'code' in error
193
+ ? String(error.code)
194
+ : undefined;
195
+ }
196
+ function delay(milliseconds) {
197
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
198
+ }
199
+ //# sourceMappingURL=RegistryGrantLock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RegistryGrantLock.js","sourceRoot":"","sources":["../../src/control-plane/RegistryGrantLock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { CompositionRoot } from '../app/CompositionRoot.js';
2
+ import { type RegistryTrust } from './ControlPlaneTypes.js';
3
+ export declare class RegistryTrustResolver {
4
+ private readonly root;
5
+ constructor(root: CompositionRoot);
6
+ resolve(requestedAlias?: string): Promise<RegistryTrust>;
7
+ forceRefresh(trust: RegistryTrust): Promise<void>;
8
+ private selectedAlias;
9
+ }
10
+ /**
11
+ * GitHub accepts HTTPS, SSH URL, and SCP-like clone coordinates for the same
12
+ * repository. Control-plane authorization must bind all three spellings to one
13
+ * stable source identity.
14
+ */
15
+ export declare function canonicalizeRegistryGitOrigin(origin: string): string;
16
+ export declare function fingerprintRegistryGitOrigin(origin: string): string;
17
+ //# sourceMappingURL=RegistryTrustResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RegistryTrustResolver.d.ts","sourceRoot":"","sources":["../../src/control-plane/RegistryTrustResolver.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,KAAK,aAAa,EAInB,MAAM,wBAAwB,CAAC;AAiBhC,qBAAa,qBAAqB;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,eAAe;IAE5C,OAAO,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAoDxD,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9D,OAAO,CAAC,aAAa;CAOtB;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAuBpE;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGnE"}