@linktr.ee/linkapp 0.0.1

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 (119) hide show
  1. package/bin/cli.js +6 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +52 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/add.d.ts +7 -0
  7. package/dist/commands/add.d.ts.map +1 -0
  8. package/dist/commands/add.js +141 -0
  9. package/dist/commands/add.js.map +1 -0
  10. package/dist/commands/build.d.ts +8 -0
  11. package/dist/commands/build.d.ts.map +1 -0
  12. package/dist/commands/build.js +84 -0
  13. package/dist/commands/build.js.map +1 -0
  14. package/dist/commands/deploy.d.ts +12 -0
  15. package/dist/commands/deploy.d.ts.map +1 -0
  16. package/dist/commands/deploy.js +158 -0
  17. package/dist/commands/deploy.js.map +1 -0
  18. package/dist/commands/dev.d.ts +7 -0
  19. package/dist/commands/dev.d.ts.map +1 -0
  20. package/dist/commands/dev.js +73 -0
  21. package/dist/commands/dev.js.map +1 -0
  22. package/dist/commands/login.d.ts +6 -0
  23. package/dist/commands/login.d.ts.map +1 -0
  24. package/dist/commands/login.js +77 -0
  25. package/dist/commands/login.js.map +1 -0
  26. package/dist/commands/logout.d.ts +6 -0
  27. package/dist/commands/logout.d.ts.map +1 -0
  28. package/dist/commands/logout.js +25 -0
  29. package/dist/commands/logout.js.map +1 -0
  30. package/dist/commands/test-url-match-rules.d.ts +7 -0
  31. package/dist/commands/test-url-match-rules.d.ts.map +1 -0
  32. package/dist/commands/test-url-match-rules.js +55 -0
  33. package/dist/commands/test-url-match-rules.js.map +1 -0
  34. package/dist/lib/auth/config.d.ts +3 -0
  35. package/dist/lib/auth/config.d.ts.map +1 -0
  36. package/dist/lib/auth/config.js +5 -0
  37. package/dist/lib/auth/config.js.map +1 -0
  38. package/dist/lib/auth/device-flow.d.ts +15 -0
  39. package/dist/lib/auth/device-flow.d.ts.map +1 -0
  40. package/dist/lib/auth/device-flow.js +28 -0
  41. package/dist/lib/auth/device-flow.js.map +1 -0
  42. package/dist/lib/auth/fetch-config.d.ts +3 -0
  43. package/dist/lib/auth/fetch-config.d.ts.map +1 -0
  44. package/dist/lib/auth/fetch-config.js +15 -0
  45. package/dist/lib/auth/fetch-config.js.map +1 -0
  46. package/dist/lib/auth/token-storage.d.ts +10 -0
  47. package/dist/lib/auth/token-storage.d.ts.map +1 -0
  48. package/dist/lib/auth/token-storage.js +79 -0
  49. package/dist/lib/auth/token-storage.js.map +1 -0
  50. package/dist/lib/build/detect-layouts.d.ts +22 -0
  51. package/dist/lib/build/detect-layouts.d.ts.map +1 -0
  52. package/dist/lib/build/detect-layouts.js +58 -0
  53. package/dist/lib/build/detect-layouts.js.map +1 -0
  54. package/dist/lib/deploy/generate-manifest-files.d.ts +2 -0
  55. package/dist/lib/deploy/generate-manifest-files.d.ts.map +1 -0
  56. package/dist/lib/deploy/generate-manifest-files.js +81 -0
  57. package/dist/lib/deploy/generate-manifest-files.js.map +1 -0
  58. package/dist/lib/deploy/pack-project.d.ts +7 -0
  59. package/dist/lib/deploy/pack-project.d.ts.map +1 -0
  60. package/dist/lib/deploy/pack-project.js +76 -0
  61. package/dist/lib/deploy/pack-project.js.map +1 -0
  62. package/dist/lib/deploy/test-url-match-rules.d.ts +6 -0
  63. package/dist/lib/deploy/test-url-match-rules.d.ts.map +1 -0
  64. package/dist/lib/deploy/test-url-match-rules.js +21 -0
  65. package/dist/lib/deploy/test-url-match-rules.js.map +1 -0
  66. package/dist/lib/deploy/upload.d.ts +12 -0
  67. package/dist/lib/deploy/upload.d.ts.map +1 -0
  68. package/dist/lib/deploy/upload.js +90 -0
  69. package/dist/lib/deploy/upload.js.map +1 -0
  70. package/dist/lib/deploy/validation.d.ts +9 -0
  71. package/dist/lib/deploy/validation.d.ts.map +1 -0
  72. package/dist/lib/deploy/validation.js +160 -0
  73. package/dist/lib/deploy/validation.js.map +1 -0
  74. package/dist/lib/utils/create-project.d.ts +8 -0
  75. package/dist/lib/utils/create-project.d.ts.map +1 -0
  76. package/dist/lib/utils/create-project.js +48 -0
  77. package/dist/lib/utils/create-project.js.map +1 -0
  78. package/dist/lib/utils/init-git.d.ts +2 -0
  79. package/dist/lib/utils/init-git.d.ts.map +1 -0
  80. package/dist/lib/utils/init-git.js +34 -0
  81. package/dist/lib/utils/init-git.js.map +1 -0
  82. package/dist/lib/utils/install-dependencies.d.ts +2 -0
  83. package/dist/lib/utils/install-dependencies.d.ts.map +1 -0
  84. package/dist/lib/utils/install-dependencies.js +20 -0
  85. package/dist/lib/utils/install-dependencies.js.map +1 -0
  86. package/dist/lib/utils/setup-runtime.d.ts +6 -0
  87. package/dist/lib/utils/setup-runtime.d.ts.map +1 -0
  88. package/dist/lib/utils/setup-runtime.js +103 -0
  89. package/dist/lib/utils/setup-runtime.js.map +1 -0
  90. package/dist/lib/vite/config-factory.d.ts +12 -0
  91. package/dist/lib/vite/config-factory.d.ts.map +1 -0
  92. package/dist/lib/vite/config-factory.js +55 -0
  93. package/dist/lib/vite/config-factory.js.map +1 -0
  94. package/dist/lib/vite/plugins/asset-versioning.d.ts +11 -0
  95. package/dist/lib/vite/plugins/asset-versioning.d.ts.map +1 -0
  96. package/dist/lib/vite/plugins/asset-versioning.js +50 -0
  97. package/dist/lib/vite/plugins/asset-versioning.js.map +1 -0
  98. package/dist/lib/vite/plugins/route-handler.d.ts +16 -0
  99. package/dist/lib/vite/plugins/route-handler.d.ts.map +1 -0
  100. package/dist/lib/vite/plugins/route-handler.js +108 -0
  101. package/dist/lib/vite/plugins/route-handler.js.map +1 -0
  102. package/dist/lib/vite/plugins/window-context.d.ts +7 -0
  103. package/dist/lib/vite/plugins/window-context.d.ts.map +1 -0
  104. package/dist/lib/vite/plugins/window-context.js +68 -0
  105. package/dist/lib/vite/plugins/window-context.js.map +1 -0
  106. package/dist/schema/config.schema.d.ts +229 -0
  107. package/dist/schema/config.schema.d.ts.map +1 -0
  108. package/dist/schema/config.schema.js +116 -0
  109. package/dist/schema/config.schema.js.map +1 -0
  110. package/dist/schema/index.d.ts +8 -0
  111. package/dist/schema/index.d.ts.map +1 -0
  112. package/dist/schema/index.js +8 -0
  113. package/dist/schema/index.js.map +1 -0
  114. package/dist/types.d.ts +140 -0
  115. package/dist/types.d.ts.map +1 -0
  116. package/dist/types.js +2 -0
  117. package/dist/types.js.map +1 -0
  118. package/package.json +70 -0
  119. package/runtime/index.html +12 -0
@@ -0,0 +1,77 @@
1
+ import pc from 'picocolors';
2
+ import * as p from '@clack/prompts';
3
+ import open from 'open';
4
+ import { getAppConfig } from '../lib/auth/config.js';
5
+ import { initiateDeviceFlow, pollAccessToken } from '../lib/auth/device-flow.js';
6
+ import { saveToken, isTokenValid } from '../lib/auth/token-storage.js';
7
+ export async function loginCommand(options) {
8
+ const env = options.qa ? 'QA' : 'Production';
9
+ console.log(pc.cyan(`🔐 Logging in to ${env}...\n`));
10
+ try {
11
+ const config = await getAppConfig(options.qa ? 'qa' : 'production');
12
+ // Check if already logged in
13
+ if (isTokenValid(config.auth.audience)) {
14
+ const shouldReauth = await p.confirm({
15
+ message: 'Already logged in. Re-authenticate?',
16
+ initialValue: false,
17
+ });
18
+ if (p.isCancel(shouldReauth) || !shouldReauth) {
19
+ console.log(pc.dim('\nLogin cancelled'));
20
+ return;
21
+ }
22
+ }
23
+ const s = p.spinner();
24
+ // Initiate device flow
25
+ s.start('Initiating device authorization');
26
+ const handle = await initiateDeviceFlow(config.auth);
27
+ s.stop('Device authorization initiated');
28
+ const { expires_in, user_code, verification_uri_complete } = handle;
29
+ const expiryMinutes = Math.floor(expires_in / 60);
30
+ console.log(pc.green('\n✓ Authorization code:'), pc.bold(user_code));
31
+ console.log(pc.dim(` ${verification_uri_complete}`));
32
+ console.log(pc.dim(` Expires in ${expiryMinutes} minutes\n`));
33
+ // Open browser
34
+ await open(verification_uri_complete);
35
+ console.log(pc.cyan('🌐 Browser opened for authentication'));
36
+ console.log(pc.dim(' If browser did not open, visit the link above\n'));
37
+ // Poll for token
38
+ s.start('Waiting for authorization');
39
+ const token = await pollAccessToken(handle);
40
+ s.stop('Authorization successful');
41
+ // Calculate expiry time
42
+ const expiresAt = token.expires_at ?? (token.expires_in ? Math.floor(Date.now() / 1000) + token.expires_in : undefined);
43
+ // Save token (this will validate token structure and permissions)
44
+ try {
45
+ if (!token.access_token) {
46
+ throw new Error('No access token received');
47
+ }
48
+ saveToken(token.access_token, config.auth.audience, expiresAt);
49
+ }
50
+ catch (validationError) {
51
+ // Token validation failed - provide specific error message
52
+ s.stop('Authorization completed but validation failed');
53
+ if (validationError instanceof Error) {
54
+ console.error(pc.red('\n✗ Token validation failed:'), validationError.message);
55
+ }
56
+ else {
57
+ console.error(pc.red('\n✗ Token validation failed:'), validationError);
58
+ }
59
+ process.exit(1);
60
+ }
61
+ console.log(pc.green('\n✓ Login successful!'));
62
+ if (expiresAt) {
63
+ const expiryDate = new Date(expiresAt * 1000).toLocaleString();
64
+ console.log(pc.dim(` Token expires: ${expiryDate}\n`));
65
+ }
66
+ }
67
+ catch (error) {
68
+ if (error instanceof Error) {
69
+ console.error(pc.red('\n✗ Login failed:'), error.message);
70
+ }
71
+ else {
72
+ console.error(pc.red('\n✗ Login failed:'), error);
73
+ }
74
+ process.exit(1);
75
+ }
76
+ }
77
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ interface LogoutOptions {
2
+ qa?: boolean;
3
+ }
4
+ export declare function logoutCommand(options: LogoutOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAKA,UAAU,aAAa;IACrB,EAAE,CAAC,EAAE,OAAO,CAAA;CACb;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,iBAuBzD"}
@@ -0,0 +1,25 @@
1
+ import pc from 'picocolors';
2
+ import open from 'open';
3
+ import { getAppConfig } from '../lib/auth/config.js';
4
+ import { removeToken } from '../lib/auth/token-storage.js';
5
+ export async function logoutCommand(options) {
6
+ const env = options.qa ? 'QA' : 'Production';
7
+ console.log(pc.cyan(`🔓 Logging out from ${env}...\n`));
8
+ try {
9
+ const config = await getAppConfig(options.qa ? 'qa' : 'production');
10
+ // Remove stored token for the specified audience
11
+ removeToken(config.auth.audience);
12
+ // Build logout URL
13
+ const logoutUrl = `${config.auth.domain}/v2/logout?client_id=${config.auth.client_id}&returnTo=${config.logout_redirect_url}`;
14
+ // Open browser to clear session
15
+ await open(logoutUrl);
16
+ console.log(pc.green('✓ Logged out successfully'));
17
+ console.log(pc.dim(' Browser opened to clear session'));
18
+ console.log(pc.dim(` If browser did not open, visit: ${logoutUrl}\n`));
19
+ }
20
+ catch (error) {
21
+ console.error(pc.red('✗ Logout failed:'), error);
22
+ process.exit(1);
23
+ }
24
+ }
25
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAM1D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAsB;IACxD,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAA;IAC5C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC,CAAC,CAAA;IAEvD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;QAEnE,iDAAiD;QACjD,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAEjC,mBAAmB;QACnB,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,wBAAwB,MAAM,CAAC,IAAI,CAAC,SAAS,aAAa,MAAM,CAAC,mBAAmB,EAAE,CAAA;QAE7H,gCAAgC;QAChC,MAAM,IAAI,CAAC,SAAS,CAAC,CAAA;QAErB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAA;QAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAA;QACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,qCAAqC,SAAS,IAAI,CAAC,CAAC,CAAA;IACzE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,KAAK,CAAC,CAAA;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ interface TestUrlMatchRulesOptions {
2
+ qa?: boolean;
3
+ endpoint?: string;
4
+ }
5
+ export declare function testUrlMatchRulesCommand(url: string, options: TestUrlMatchRulesOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=test-url-match-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-url-match-rules.d.ts","sourceRoot":"","sources":["../../src/commands/test-url-match-rules.ts"],"names":[],"mappings":"AAOA,UAAU,wBAAwB;IAChC,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB,iBAqD5F"}
@@ -0,0 +1,55 @@
1
+ import pc from 'picocolors';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { getAppConfig } from '../lib/auth/config.js';
5
+ import { getToken } from '../lib/auth/token-storage.js';
6
+ import { testUrlMatchRules } from '../lib/deploy/test-url-match-rules.js';
7
+ export async function testUrlMatchRulesCommand(url, options) {
8
+ console.log(pc.cyan(`🧪 Testing URL match rules for: ${url}\n`));
9
+ try {
10
+ const config = await getAppConfig(options.qa ? 'qa' : 'production');
11
+ const projectPath = process.cwd();
12
+ // Check authentication
13
+ const accessToken = getToken(config.auth.audience);
14
+ if (!accessToken) {
15
+ console.log(pc.red('✗ Not authenticated'));
16
+ console.log(pc.dim(` Run: linkapp login${options.qa ? ' --qa' : ''}\n`));
17
+ process.exit(1);
18
+ }
19
+ // Look up the local url_match_rules.json file
20
+ const urlMatchRulesPath = join(projectPath, 'url_match_rules.json');
21
+ if (!existsSync(urlMatchRulesPath)) {
22
+ console.log(pc.red('✗ url_match_rules.json not found in current directory\n'));
23
+ process.exit(1);
24
+ }
25
+ console.log(pc.cyan('📋 Loading URL match rules from url_match_rules.json...'));
26
+ const urlMatchRulesString = readFileSync(urlMatchRulesPath, 'utf8');
27
+ if (!urlMatchRulesString) {
28
+ console.log(pc.red('✗ url_match_rules.json is empty\n'));
29
+ process.exit(1);
30
+ }
31
+ let urlMatchRules = null;
32
+ try {
33
+ urlMatchRules = JSON.parse(urlMatchRulesString);
34
+ console.log(pc.green('✓ URL match rules loaded successfully\n'));
35
+ }
36
+ catch (error) {
37
+ console.log(pc.red('✗ url_match_rules.json is invalid JSON\n'));
38
+ process.exit(1);
39
+ }
40
+ // Test URL against match rules
41
+ console.log(pc.cyan('🔍 Testing URL against match rules...\n'));
42
+ const apiUrl = options.endpoint ?? `${config.link_types_url}/link-types`;
43
+ const result = await testUrlMatchRules(apiUrl, url, urlMatchRules, accessToken);
44
+ const success = result.success;
45
+ console.log(`${success ? pc.green('🎉 Success') : pc.red('❌ Failed')}\n`);
46
+ console.log(pc.bold('Test Result:'));
47
+ console.log(JSON.stringify(result, null, 2));
48
+ console.log();
49
+ }
50
+ catch (error) {
51
+ console.error(pc.red('\n✗ Test failed:'), error);
52
+ process.exit(1);
53
+ }
54
+ }
55
+ //# sourceMappingURL=test-url-match-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-url-match-rules.js","sourceRoot":"","sources":["../../src/commands/test-url-match-rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AppConfig, Environment } from '../../types.js';
2
+ export declare function getAppConfig(env?: Environment): Promise<AppConfig>;
3
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG5D,wBAAsB,YAAY,CAAC,GAAG,GAAE,WAA0B,GAAG,OAAO,CAAC,SAAS,CAAC,CAEtF"}
@@ -0,0 +1,5 @@
1
+ import { fetchAppConfig } from './fetch-config.js';
2
+ export async function getAppConfig(env = 'production') {
3
+ return await fetchAppConfig(env);
4
+ }
5
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/lib/auth/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAElD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAmB,YAAY;IAChE,OAAO,MAAM,cAAc,CAAC,GAAG,CAAC,CAAA;AAClC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { BaseClient, DeviceFlowHandle, TokenSet } from 'openid-client';
2
+ interface AuthConfig {
3
+ domain: string;
4
+ client_id: string;
5
+ audience: string;
6
+ }
7
+ export declare function initiateDeviceFlow(config: AuthConfig): Promise<DeviceFlowHandle<BaseClient>>;
8
+ export declare function pollForToken(_config: AuthConfig, _deviceCode: string, _interval: number): Promise<{
9
+ access_token: string;
10
+ token_type: string;
11
+ expires_in?: number;
12
+ }>;
13
+ export declare function pollAccessToken(handle: DeviceFlowHandle<BaseClient>): Promise<TokenSet>;
14
+ export {};
15
+ //# sourceMappingURL=device-flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/device-flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAkB,QAAQ,EAAE,MAAM,eAAe,CAAA;AAEtF,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAUlG;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,UAAU,EACnB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAK5E;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,gBAAgB,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAS7F"}
@@ -0,0 +1,28 @@
1
+ import { errors, Issuer } from 'openid-client';
2
+ export async function initiateDeviceFlow(config) {
3
+ const { domain, client_id, audience } = config;
4
+ const auth0Issuer = await Issuer.discover(domain);
5
+ const client = new auth0Issuer.Client({
6
+ client_id,
7
+ token_endpoint_auth_method: 'none',
8
+ });
9
+ return await client.deviceAuthorization({ scope: '', audience });
10
+ }
11
+ export async function pollForToken(_config, _deviceCode, _interval) {
12
+ // For the new implementation, we don't use deviceCode directly
13
+ // The device flow handle returned by initiateDeviceFlow contains the poll method
14
+ // This function signature is kept for compatibility but should be updated in the caller
15
+ throw new Error('This function should not be called directly. Use the DeviceFlowHandle.poll() method instead.');
16
+ }
17
+ export async function pollAccessToken(handle) {
18
+ try {
19
+ return await handle.poll();
20
+ }
21
+ catch (err) {
22
+ if (err instanceof errors.OPError) {
23
+ throw new Error(err.error_description ?? err.message);
24
+ }
25
+ throw err;
26
+ }
27
+ }
28
+ //# sourceMappingURL=device-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../../src/lib/auth/device-flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAE,MAAM,EAAY,MAAM,eAAe,CAAA;AAQtF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAkB;IACzD,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IAE9C,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IACjD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC;QACpC,SAAS;QACT,0BAA0B,EAAE,MAAM;KACnC,CAAC,CAAA;IAEF,OAAO,MAAM,MAAM,CAAC,mBAAmB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAmB,EACnB,WAAmB,EACnB,SAAiB;IAEjB,+DAA+D;IAC/D,iFAAiF;IACjF,wFAAwF;IACxF,MAAM,IAAI,KAAK,CAAC,8FAA8F,CAAC,CAAA;AACjH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAoC;IACxE,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,iBAAiB,IAAI,GAAG,CAAC,OAAO,CAAC,CAAA;QACvD,CAAC;QACD,MAAM,GAAG,CAAA;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AppConfig, Environment } from '../../types.js';
2
+ export declare function fetchAppConfig(env?: Environment): Promise<AppConfig>;
3
+ //# sourceMappingURL=fetch-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-config.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/fetch-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE5D,wBAAsB,cAAc,CAAC,GAAG,GAAE,WAA0B,GAAG,OAAO,CAAC,SAAS,CAAC,CAYxF"}
@@ -0,0 +1,15 @@
1
+ import axios from 'axios';
2
+ export async function fetchAppConfig(env = 'production') {
3
+ const configUrl = `https://link-types-config.${env}.linktr.ee/create-link-app.json`;
4
+ try {
5
+ const response = await axios.get(configUrl);
6
+ return response.data;
7
+ }
8
+ catch (error) {
9
+ if (axios.isAxiosError(error)) {
10
+ throw new Error(`Failed to fetch config from ${configUrl}: ${error.message}`);
11
+ }
12
+ throw error;
13
+ }
14
+ }
15
+ //# sourceMappingURL=fetch-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-config.js","sourceRoot":"","sources":["../../../src/lib/auth/fetch-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAmB,YAAY;IAClE,MAAM,SAAS,GAAG,6BAA6B,GAAG,iCAAiC,CAAA;IAEnF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAY,SAAS,CAAC,CAAA;QACtD,OAAO,QAAQ,CAAC,IAAI,CAAA;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,+BAA+B,SAAS,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAC/E,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Validates that a JWT token has the correct structure and permissions
3
+ * @throws Error if token is invalid or lacks permissions
4
+ */
5
+ export declare function validateTokenStructure(tokenString: string): void;
6
+ export declare function saveToken(token: string, audience: string, expiresAt?: number): void;
7
+ export declare function getToken(audience: string): string | null;
8
+ export declare function removeToken(audience?: string): void;
9
+ export declare function isTokenValid(audience: string): boolean;
10
+ //# sourceMappingURL=token-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-storage.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/token-storage.ts"],"names":[],"mappings":"AAqBA;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAahE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAgBnF;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwBxD;AAED,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAkBnD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD"}
@@ -0,0 +1,79 @@
1
+ import { homedir } from 'node:os';
2
+ import { join } from 'node:path';
3
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
4
+ import jwt from 'jsonwebtoken';
5
+ const CONFIG_DIR = join(homedir(), '.config', 'linkapp');
6
+ const TOKEN_FILE = join(CONFIG_DIR, 'auth-token.json');
7
+ const TOKEN_EXPIRY_THRESHOLD_SECONDS = 60; // Consider tokens as expired within the last 60s of actual expiry
8
+ /**
9
+ * Validates that a JWT token has the correct structure and permissions
10
+ * @throws Error if token is invalid or lacks permissions
11
+ */
12
+ export function validateTokenStructure(tokenString) {
13
+ const payload = jwt.decode(tokenString, { json: true });
14
+ if (!payload) {
15
+ throw new Error('There was an error parsing the access token, please try logging in again');
16
+ }
17
+ const permissions = payload.permissions ?? [];
18
+ if (permissions.length === 0) {
19
+ throw new Error('Login request was successful, but the authenticated user does not have appropriate permissions to view or modify LinkApps');
20
+ }
21
+ }
22
+ export function saveToken(token, audience, expiresAt) {
23
+ // Validate token structure and permissions before saving
24
+ validateTokenStructure(token);
25
+ // Ensure config directory exists
26
+ if (!existsSync(CONFIG_DIR)) {
27
+ mkdirSync(CONFIG_DIR, { recursive: true });
28
+ }
29
+ const data = {
30
+ accessToken: token,
31
+ expiresAt,
32
+ audience,
33
+ };
34
+ writeFileSync(TOKEN_FILE, JSON.stringify(data, null, 2), 'utf-8');
35
+ }
36
+ export function getToken(audience) {
37
+ if (!existsSync(TOKEN_FILE)) {
38
+ return null;
39
+ }
40
+ try {
41
+ const data = JSON.parse(readFileSync(TOKEN_FILE, 'utf-8'));
42
+ // Check if token is for the correct audience
43
+ if (data.audience !== audience) {
44
+ return null;
45
+ }
46
+ // Check if token is expired (with threshold buffer)
47
+ if (data.expiresAt && data.expiresAt - TOKEN_EXPIRY_THRESHOLD_SECONDS < Math.floor(Date.now() / 1000)) {
48
+ removeToken();
49
+ return null;
50
+ }
51
+ return data.accessToken;
52
+ }
53
+ catch (error) {
54
+ console.error('Failed to read token:', error);
55
+ return null;
56
+ }
57
+ }
58
+ export function removeToken(audience) {
59
+ if (!existsSync(TOKEN_FILE)) {
60
+ return;
61
+ }
62
+ // If audience is specified, only remove token if it matches
63
+ if (audience) {
64
+ try {
65
+ const data = JSON.parse(readFileSync(TOKEN_FILE, 'utf-8'));
66
+ if (data.audience !== audience) {
67
+ return; // Don't remove token for different audience
68
+ }
69
+ }
70
+ catch (error) {
71
+ // If we can't read the file, remove it anyway
72
+ }
73
+ }
74
+ unlinkSync(TOKEN_FILE);
75
+ }
76
+ export function isTokenValid(audience) {
77
+ return getToken(audience) !== null;
78
+ }
79
+ //# sourceMappingURL=token-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-storage.js","sourceRoot":"","sources":["../../../src/lib/auth/token-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface Layout {
2
+ name: string;
3
+ fileName: string;
4
+ displayName: string;
5
+ }
6
+ export interface LayoutDetection {
7
+ layouts: Layout[];
8
+ hasLayout: boolean;
9
+ }
10
+ /**
11
+ * Detects all layout files in the project's /app directory
12
+ * Excludes layout.tsx and globals.css
13
+ */
14
+ export declare function detectLayouts(projectPath: string): LayoutDetection;
15
+ /**
16
+ * Validates that required layout files exist
17
+ */
18
+ export declare function validateLayouts(projectPath: string): {
19
+ valid: boolean;
20
+ errors: string[];
21
+ };
22
+ //# sourceMappingURL=detect-layouts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-layouts.d.ts","sourceRoot":"","sources":["../../../src/lib/build/detect-layouts.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;CACnB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAuClE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAmBzF"}
@@ -0,0 +1,58 @@
1
+ import { existsSync, readdirSync } from 'node:fs';
2
+ import { join, basename } from 'node:path';
3
+ /**
4
+ * Detects all layout files in the project's /app directory
5
+ * Excludes layout.tsx and globals.css
6
+ */
7
+ export function detectLayouts(projectPath) {
8
+ const appDir = join(projectPath, 'app');
9
+ if (!existsSync(appDir)) {
10
+ return { layouts: [], hasLayout: false };
11
+ }
12
+ const files = readdirSync(appDir);
13
+ const layouts = [];
14
+ for (const file of files) {
15
+ // Skip layout.tsx, main.tsx, globals.css, and non-tsx files
16
+ if (file === 'layout.tsx' ||
17
+ file === 'layout.ts' ||
18
+ file === 'main.tsx' ||
19
+ file === 'main.ts' ||
20
+ file === 'globals.css' ||
21
+ (!file.endsWith('.tsx') && !file.endsWith('.ts'))) {
22
+ continue;
23
+ }
24
+ const name = basename(file, file.endsWith('.tsx') ? '.tsx' : '.ts');
25
+ const displayName = name.charAt(0).toUpperCase() + name.slice(1);
26
+ layouts.push({
27
+ name,
28
+ fileName: file,
29
+ displayName,
30
+ });
31
+ }
32
+ const hasLayout = existsSync(join(appDir, 'layout.tsx')) || existsSync(join(appDir, 'layout.ts'));
33
+ return {
34
+ layouts,
35
+ hasLayout,
36
+ };
37
+ }
38
+ /**
39
+ * Validates that required layout files exist
40
+ */
41
+ export function validateLayouts(projectPath) {
42
+ const detection = detectLayouts(projectPath);
43
+ const errors = [];
44
+ // classic.tsx is always required
45
+ const hasClassic = detection.layouts.some(l => l.name === 'classic');
46
+ if (!hasClassic) {
47
+ errors.push('app/classic.tsx is required. This is the default layout for your Link App.');
48
+ }
49
+ // Layout wrapper is required
50
+ if (!detection.hasLayout) {
51
+ errors.push('Layout wrapper not found. Create app/layout.tsx');
52
+ }
53
+ return {
54
+ valid: errors.length === 0,
55
+ errors,
56
+ };
57
+ }
58
+ //# sourceMappingURL=detect-layouts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-layouts.js","sourceRoot":"","sources":["../../../src/lib/build/detect-layouts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAa1C;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IAEvC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;IAC1C,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,MAAM,OAAO,GAAa,EAAE,CAAA;IAE5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,4DAA4D;QAC5D,IACE,IAAI,KAAK,YAAY;YACrB,IAAI,KAAK,WAAW;YACpB,IAAI,KAAK,UAAU;YACnB,IAAI,KAAK,SAAS;YAClB,IAAI,KAAK,aAAa;YACtB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EACjD,CAAC;YACD,SAAQ;QACV,CAAC;QAED,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACnE,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAEhE,OAAO,CAAC,IAAI,CAAC;YACX,IAAI;YACJ,QAAQ,EAAE,IAAI;YACd,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;IAEjG,OAAO;QACL,OAAO;QACP,SAAS;KACV,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,SAAS,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;IAC5C,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,iCAAiC;IACjC,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAA;IACpE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAA;IAC3F,CAAC;IAED,6BAA6B;IAC7B,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAA;IAChE,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QAC1B,MAAM;KACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function generateManifestFiles(projectPath?: string): Promise<void>;
2
+ //# sourceMappingURL=generate-manifest-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-manifest-files.d.ts","sourceRoot":"","sources":["../../../src/lib/deploy/generate-manifest-files.ts"],"names":[],"mappings":"AAmCA,wBAAsB,qBAAqB,CAAC,WAAW,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuE9F"}
@@ -0,0 +1,81 @@
1
+ import { writeFileSync, existsSync, mkdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { createJiti } from 'jiti';
4
+ /**
5
+ * Convert camelCase string to snake_case
6
+ */
7
+ function toSnakeCase(str) {
8
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
9
+ }
10
+ /**
11
+ * Recursively convert all camelCase keys to snake_case in an object
12
+ */
13
+ function convertKeysToSnakeCase(obj) {
14
+ if (obj === null || obj === undefined) {
15
+ return obj;
16
+ }
17
+ if (Array.isArray(obj)) {
18
+ return obj.map(item => convertKeysToSnakeCase(item));
19
+ }
20
+ if (typeof obj === 'object' && obj.constructor === Object) {
21
+ return Object.keys(obj).reduce((acc, key) => {
22
+ const snakeKey = toSnakeCase(key);
23
+ acc[snakeKey] = convertKeysToSnakeCase(obj[key]);
24
+ return acc;
25
+ }, {});
26
+ }
27
+ return obj;
28
+ }
29
+ export async function generateManifestFiles(projectPath = process.cwd()) {
30
+ // Check for config in root first, then .config directory
31
+ const rootConfigPath = join(projectPath, 'linkapp.config.ts');
32
+ const nestedConfigPath = join(projectPath, '.config', 'linkapp.config.ts');
33
+ const configPath = existsSync(rootConfigPath) ? rootConfigPath : nestedConfigPath;
34
+ if (!existsSync(configPath)) {
35
+ throw new Error('Config file not found: linkapp.config.ts');
36
+ }
37
+ try {
38
+ // Create .linkapp directory for generated files
39
+ const linkappDir = join(projectPath, '.linkapp');
40
+ if (!existsSync(linkappDir)) {
41
+ mkdirSync(linkappDir, { recursive: true });
42
+ }
43
+ // Load the TypeScript config using jiti
44
+ const jiti = createJiti(import.meta.url, {
45
+ interopDefault: true,
46
+ moduleCache: false,
47
+ });
48
+ const config = jiti(configPath);
49
+ // Generate manifest.json (convert all camelCase keys to snake_case for API)
50
+ // Note: id is kept in config for internal use but NOT sent to the API
51
+ const manifestData = {
52
+ name: config.manifest.name,
53
+ tagline: config.manifest.tagline,
54
+ description: config.manifest.description,
55
+ manifestVersion: config.manifest.manifestVersion,
56
+ version: config.manifest.version,
57
+ supportingLinks: config.manifest.supportingLinks,
58
+ category: config.manifest.category,
59
+ searchTerms: config.manifest.searchTerms,
60
+ author: config.manifest.author,
61
+ };
62
+ const manifest = convertKeysToSnakeCase(manifestData);
63
+ writeFileSync(join(linkappDir, 'manifest.json'), JSON.stringify(manifest, null, 2), 'utf-8');
64
+ // Generate settings.json (keep camelCase - API expects camelCase for settings)
65
+ // Note: supportsFeaturedLayout is kept in config but NOT sent to the API
66
+ const settings = {
67
+ title: config.settings.title,
68
+ overview: config.settings.overview,
69
+ elements: config.settings.elements,
70
+ };
71
+ writeFileSync(join(linkappDir, 'settings.json'), JSON.stringify(settings, null, 2), 'utf-8');
72
+ // Generate url_match_rules.json if present
73
+ if (config.urlMatchRules) {
74
+ writeFileSync(join(linkappDir, 'url_match_rules.json'), JSON.stringify(config.urlMatchRules, null, 2), 'utf-8');
75
+ }
76
+ }
77
+ catch (error) {
78
+ throw new Error(`Failed to generate manifest files: ${error instanceof Error ? error.message : error}`);
79
+ }
80
+ }
81
+ //# sourceMappingURL=generate-manifest-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-manifest-files.js","sourceRoot":"","sources":["../../../src/lib/deploy/generate-manifest-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface PackOptions {
2
+ projectPath?: string;
3
+ outputPath?: string;
4
+ }
5
+ export declare function packProject(options?: PackOptions): Promise<string[]>;
6
+ export {};
7
+ //# sourceMappingURL=pack-project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack-project.d.ts","sourceRoot":"","sources":["../../../src/lib/deploy/pack-project.ts"],"names":[],"mappings":"AAIA,UAAU,WAAW;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAoF9E"}