@ankhorage/studio 0.0.20 → 0.1.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 (211) hide show
  1. package/README.md +1 -2
  2. package/dist/cli/index.d.ts +4 -4
  3. package/dist/cli/index.d.ts.map +1 -1
  4. package/dist/cli/index.js +81 -56
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/core/constants.d.ts.map +1 -1
  7. package/dist/core/constants.js +17 -6
  8. package/dist/core/constants.js.map +1 -1
  9. package/dist/hooks/useProjects.js +1 -1
  10. package/dist/hooks/useProjects.js.map +1 -1
  11. package/dist/host/createStudioHost.d.ts +13 -0
  12. package/dist/host/createStudioHost.d.ts.map +1 -0
  13. package/dist/host/createStudioHost.js +16 -0
  14. package/dist/host/createStudioHost.js.map +1 -0
  15. package/dist/host/http/security.d.ts +2 -0
  16. package/dist/host/http/security.d.ts.map +1 -0
  17. package/dist/host/http/security.js +55 -0
  18. package/dist/host/http/security.js.map +1 -0
  19. package/dist/host/http/server.d.ts +16 -0
  20. package/dist/host/http/server.d.ts.map +1 -0
  21. package/dist/host/http/server.js +549 -0
  22. package/dist/host/http/server.js.map +1 -0
  23. package/dist/host/layout/auth/resolveAuthLayoutPlan.d.ts +38 -0
  24. package/dist/host/layout/auth/resolveAuthLayoutPlan.d.ts.map +1 -0
  25. package/dist/host/layout/auth/resolveAuthLayoutPlan.js +262 -0
  26. package/dist/host/layout/auth/resolveAuthLayoutPlan.js.map +1 -0
  27. package/dist/host/layout/layoutGenerator.d.ts +19 -0
  28. package/dist/host/layout/layoutGenerator.d.ts.map +1 -0
  29. package/dist/host/layout/layoutGenerator.js +418 -0
  30. package/dist/host/layout/layoutGenerator.js.map +1 -0
  31. package/dist/host/layout/templates/auth/adapter.d.ts +6 -0
  32. package/dist/host/layout/templates/auth/adapter.d.ts.map +1 -0
  33. package/dist/host/layout/templates/auth/adapter.js +94 -0
  34. package/dist/host/layout/templates/auth/adapter.js.map +1 -0
  35. package/dist/host/layout/templates/auth/screen.d.ts +12 -0
  36. package/dist/host/layout/templates/auth/screen.d.ts.map +1 -0
  37. package/dist/host/layout/templates/auth/screen.js +648 -0
  38. package/dist/host/layout/templates/auth/screen.js.map +1 -0
  39. package/dist/host/layout/templates/auth/session.d.ts +2 -0
  40. package/dist/host/layout/templates/auth/session.d.ts.map +1 -0
  41. package/dist/host/layout/templates/auth/session.js +326 -0
  42. package/dist/host/layout/templates/auth/session.js.map +1 -0
  43. package/dist/host/layout/templates/auth/signOut.d.ts +2 -0
  44. package/dist/host/layout/templates/auth/signOut.d.ts.map +1 -0
  45. package/dist/host/layout/templates/auth/signOut.js +43 -0
  46. package/dist/host/layout/templates/auth/signOut.js.map +1 -0
  47. package/dist/host/layout/templates/index.d.ts +11 -0
  48. package/dist/host/layout/templates/index.d.ts.map +1 -0
  49. package/dist/host/layout/templates/index.js +10 -0
  50. package/dist/host/layout/templates/index.js.map +1 -0
  51. package/dist/host/layout/templates/navigation.d.ts +16 -0
  52. package/dist/host/layout/templates/navigation.d.ts.map +1 -0
  53. package/dist/host/layout/templates/navigation.js +332 -0
  54. package/dist/host/layout/templates/navigation.js.map +1 -0
  55. package/dist/host/layout/templates/nestedLayout.d.ts +7 -0
  56. package/dist/host/layout/templates/nestedLayout.d.ts.map +1 -0
  57. package/dist/host/layout/templates/nestedLayout.js +56 -0
  58. package/dist/host/layout/templates/nestedLayout.js.map +1 -0
  59. package/dist/host/layout/templates/redirect.d.ts +2 -0
  60. package/dist/host/layout/templates/redirect.d.ts.map +1 -0
  61. package/dist/host/layout/templates/redirect.js +10 -0
  62. package/dist/host/layout/templates/redirect.js.map +1 -0
  63. package/dist/host/layout/templates/rootLayout.d.ts +28 -0
  64. package/dist/host/layout/templates/rootLayout.d.ts.map +1 -0
  65. package/dist/host/layout/templates/rootLayout.js +507 -0
  66. package/dist/host/layout/templates/rootLayout.js.map +1 -0
  67. package/dist/host/layout/templates/screen.d.ts +6 -0
  68. package/dist/host/layout/templates/screen.d.ts.map +1 -0
  69. package/dist/host/layout/templates/screen.js +94 -0
  70. package/dist/host/layout/templates/screen.js.map +1 -0
  71. package/dist/host/layout/templates/utils/routes.d.ts +3 -0
  72. package/dist/host/layout/templates/utils/routes.d.ts.map +1 -0
  73. package/dist/host/layout/templates/utils/routes.js +15 -0
  74. package/dist/host/layout/templates/utils/routes.js.map +1 -0
  75. package/dist/host/layout/templates/utils/strings.d.ts +3 -0
  76. package/dist/host/layout/templates/utils/strings.d.ts.map +1 -0
  77. package/dist/host/layout/templates/utils/strings.js +7 -0
  78. package/dist/host/layout/templates/utils/strings.js.map +1 -0
  79. package/dist/host/layout/utils/escapeStringLiteral.d.ts +2 -0
  80. package/dist/host/layout/utils/escapeStringLiteral.d.ts.map +1 -0
  81. package/dist/host/layout/utils/escapeStringLiteral.js +8 -0
  82. package/dist/host/layout/utils/escapeStringLiteral.js.map +1 -0
  83. package/dist/host/manifestSystem/auth/index.d.ts +2 -0
  84. package/dist/host/manifestSystem/auth/index.d.ts.map +1 -0
  85. package/dist/host/manifestSystem/auth/index.js +2 -0
  86. package/dist/host/manifestSystem/auth/index.js.map +1 -0
  87. package/dist/host/manifestSystem/auth/shared/global.auth.system.tpl.d.ts +4 -0
  88. package/dist/host/manifestSystem/auth/shared/global.auth.system.tpl.d.ts.map +1 -0
  89. package/dist/host/manifestSystem/auth/shared/global.auth.system.tpl.js +7 -0
  90. package/dist/host/manifestSystem/auth/shared/global.auth.system.tpl.js.map +1 -0
  91. package/dist/host/manifestSystem/auth/shared/index.d.ts +3 -0
  92. package/dist/host/manifestSystem/auth/shared/index.d.ts.map +1 -0
  93. package/dist/host/manifestSystem/auth/shared/index.js +8 -0
  94. package/dist/host/manifestSystem/auth/shared/index.js.map +1 -0
  95. package/dist/host/manifestSystem/index.d.ts +5 -0
  96. package/dist/host/manifestSystem/index.d.ts.map +1 -0
  97. package/dist/host/manifestSystem/index.js +23 -0
  98. package/dist/host/manifestSystem/index.js.map +1 -0
  99. package/dist/host/manifestSystem/types.d.ts +8 -0
  100. package/dist/host/manifestSystem/types.d.ts.map +1 -0
  101. package/dist/host/manifestSystem/types.js +2 -0
  102. package/dist/host/manifestSystem/types.js.map +1 -0
  103. package/dist/host/modules/catalog.d.ts +40 -0
  104. package/dist/host/modules/catalog.d.ts.map +1 -0
  105. package/dist/host/modules/catalog.js +112 -0
  106. package/dist/host/modules/catalog.js.map +1 -0
  107. package/dist/host/modules/layout.d.ts +7 -0
  108. package/dist/host/modules/layout.d.ts.map +1 -0
  109. package/dist/host/modules/layout.js +2 -0
  110. package/dist/host/modules/layout.js.map +1 -0
  111. package/dist/host/modules/runtime/LocalFsTargetAdapter.d.ts +34 -0
  112. package/dist/host/modules/runtime/LocalFsTargetAdapter.d.ts.map +1 -0
  113. package/dist/host/modules/runtime/LocalFsTargetAdapter.js +85 -0
  114. package/dist/host/modules/runtime/LocalFsTargetAdapter.js.map +1 -0
  115. package/dist/host/orchestrator/generatedAppFiles.d.ts +8 -0
  116. package/dist/host/orchestrator/generatedAppFiles.d.ts.map +1 -0
  117. package/dist/host/orchestrator/generatedAppFiles.js +125 -0
  118. package/dist/host/orchestrator/generatedAppFiles.js.map +1 -0
  119. package/dist/host/orchestrator/generatedRouteCleanup.d.ts +5 -0
  120. package/dist/host/orchestrator/generatedRouteCleanup.d.ts.map +1 -0
  121. package/dist/host/orchestrator/generatedRouteCleanup.js +117 -0
  122. package/dist/host/orchestrator/generatedRouteCleanup.js.map +1 -0
  123. package/dist/host/orchestrator/infraGenerator.d.ts +35 -0
  124. package/dist/host/orchestrator/infraGenerator.d.ts.map +1 -0
  125. package/dist/host/orchestrator/infraGenerator.js +135 -0
  126. package/dist/host/orchestrator/infraGenerator.js.map +1 -0
  127. package/dist/host/orchestrator/infraRuntime.d.ts +38 -0
  128. package/dist/host/orchestrator/infraRuntime.d.ts.map +1 -0
  129. package/dist/host/orchestrator/infraRuntime.js +227 -0
  130. package/dist/host/orchestrator/infraRuntime.js.map +1 -0
  131. package/dist/host/orchestrator/infraValidation.d.ts +3 -0
  132. package/dist/host/orchestrator/infraValidation.d.ts.map +1 -0
  133. package/dist/host/orchestrator/infraValidation.js +59 -0
  134. package/dist/host/orchestrator/infraValidation.js.map +1 -0
  135. package/dist/host/orchestrator/moduleManager.d.ts +86 -0
  136. package/dist/host/orchestrator/moduleManager.d.ts.map +1 -0
  137. package/dist/host/orchestrator/moduleManager.js +312 -0
  138. package/dist/host/orchestrator/moduleManager.js.map +1 -0
  139. package/dist/host/orchestrator/projectDeletion.d.ts +27 -0
  140. package/dist/host/orchestrator/projectDeletion.d.ts.map +1 -0
  141. package/dist/host/orchestrator/projectDeletion.js +242 -0
  142. package/dist/host/orchestrator/projectDeletion.js.map +1 -0
  143. package/dist/host/orchestrator/projectManager.d.ts +87 -0
  144. package/dist/host/orchestrator/projectManager.d.ts.map +1 -0
  145. package/dist/host/orchestrator/projectManager.js +371 -0
  146. package/dist/host/orchestrator/projectManager.js.map +1 -0
  147. package/dist/host/orchestrator/projectPaths.d.ts +4 -0
  148. package/dist/host/orchestrator/projectPaths.d.ts.map +1 -0
  149. package/dist/host/orchestrator/projectPaths.js +25 -0
  150. package/dist/host/orchestrator/projectPaths.js.map +1 -0
  151. package/dist/host/orchestrator/projectStore.d.ts +24 -0
  152. package/dist/host/orchestrator/projectStore.d.ts.map +1 -0
  153. package/dist/host/orchestrator/projectStore.js +155 -0
  154. package/dist/host/orchestrator/projectStore.js.map +1 -0
  155. package/dist/host/orchestrator/resolveMutations.d.ts +3 -0
  156. package/dist/host/orchestrator/resolveMutations.d.ts.map +1 -0
  157. package/dist/host/orchestrator/resolveMutations.js +12 -0
  158. package/dist/host/orchestrator/resolveMutations.js.map +1 -0
  159. package/dist/host/orchestrator/scaffolder.d.ts +33 -0
  160. package/dist/host/orchestrator/scaffolder.d.ts.map +1 -0
  161. package/dist/host/orchestrator/scaffolder.js +246 -0
  162. package/dist/host/orchestrator/scaffolder.js.map +1 -0
  163. package/dist/host/orchestrator/templates.d.ts +83 -0
  164. package/dist/host/orchestrator/templates.d.ts.map +1 -0
  165. package/dist/host/orchestrator/templates.js +355 -0
  166. package/dist/host/orchestrator/templates.js.map +1 -0
  167. package/dist/host/orchestrator/workspaceRuntime.d.ts +2 -0
  168. package/dist/host/orchestrator/workspaceRuntime.d.ts.map +1 -0
  169. package/dist/host/orchestrator/workspaceRuntime.js +82 -0
  170. package/dist/host/orchestrator/workspaceRuntime.js.map +1 -0
  171. package/dist/host/templateRegistry/index.d.ts +16 -0
  172. package/dist/host/templateRegistry/index.d.ts.map +1 -0
  173. package/dist/host/templateRegistry/index.js +74 -0
  174. package/dist/host/templateRegistry/index.js.map +1 -0
  175. package/dist/host/utils/requirementsInference.d.ts +4 -0
  176. package/dist/host/utils/requirementsInference.d.ts.map +1 -0
  177. package/dist/host/utils/requirementsInference.js +49 -0
  178. package/dist/host/utils/requirementsInference.js.map +1 -0
  179. package/dist/host/utils/trimOutput.d.ts +7 -0
  180. package/dist/host/utils/trimOutput.d.ts.map +1 -0
  181. package/dist/host/utils/trimOutput.js +32 -0
  182. package/dist/host/utils/trimOutput.js.map +1 -0
  183. package/dist/host/utils/workspaceRoot.d.ts +2 -0
  184. package/dist/host/utils/workspaceRoot.d.ts.map +1 -0
  185. package/dist/host/utils/workspaceRoot.js +33 -0
  186. package/dist/host/utils/workspaceRoot.js.map +1 -0
  187. package/dist/host/zoraExtensions/index.d.ts +11 -0
  188. package/dist/host/zoraExtensions/index.d.ts.map +1 -0
  189. package/dist/host/zoraExtensions/index.js +54 -0
  190. package/dist/host/zoraExtensions/index.js.map +1 -0
  191. package/dist/runtime/appExtensionRegistry.d.ts +3 -0
  192. package/dist/runtime/appExtensionRegistry.d.ts.map +1 -0
  193. package/dist/runtime/appExtensionRegistry.js +8 -0
  194. package/dist/runtime/appExtensionRegistry.js.map +1 -0
  195. package/dist/runtime/index.d.ts +8 -4
  196. package/dist/runtime/index.d.ts.map +1 -1
  197. package/dist/runtime/index.js +8 -4
  198. package/dist/runtime/index.js.map +1 -1
  199. package/dist/runtime/registry.d.ts +7 -0
  200. package/dist/runtime/registry.d.ts.map +1 -0
  201. package/dist/runtime/registry.js +7 -0
  202. package/dist/runtime/registry.js.map +1 -0
  203. package/dist/runtime/runtimeActions.d.ts +19 -0
  204. package/dist/runtime/runtimeActions.d.ts.map +1 -0
  205. package/dist/runtime/runtimeActions.js +5 -0
  206. package/dist/runtime/runtimeActions.js.map +1 -0
  207. package/dist/runtime/useRuntimeAction.d.ts +10 -0
  208. package/dist/runtime/useRuntimeAction.d.ts.map +1 -0
  209. package/dist/runtime/useRuntimeAction.js +30 -0
  210. package/dist/runtime/useRuntimeAction.js.map +1 -0
  211. package/package.json +35 -3
@@ -0,0 +1,326 @@
1
+ export function getAuthSessionTs() {
2
+ return `import type { AuthAdapter, AuthSession, AuthUser } from '@ankhorage/contracts/auth';
3
+
4
+ export const AUTH_SESSION_STORAGE_KEY = 'ankh.auth.session';
5
+
6
+ const AUTH_REFRESH_THRESHOLD_MS = 60_000;
7
+ const AUTH_EXPIRY_SKEW_MS = 5_000;
8
+
9
+ let memorySession: AuthSession | null = null;
10
+ const authSessionListeners = new Set<() => void>();
11
+
12
+ interface AuthStorageLike {
13
+ getItem(key: string): string | null;
14
+ setItem(key: string, value: string): void;
15
+ removeItem(key: string): void;
16
+ }
17
+
18
+ export const authSessionStorage = {
19
+ getItem(key: string): string | null {
20
+ return readLocalStorage(key);
21
+ },
22
+
23
+ setItem(key: string, value: string): void {
24
+ writeLocalStorage(key, value);
25
+ },
26
+
27
+ removeItem(key: string): void {
28
+ removeLocalStorage(key);
29
+ },
30
+ };
31
+
32
+ function notifyAuthSessionChanged(): void {
33
+ for (const listener of authSessionListeners) {
34
+ try {
35
+ listener();
36
+ } catch {
37
+ // Listener errors must not break session persistence.
38
+ }
39
+ }
40
+ }
41
+
42
+ export function subscribeToAuthSessionChanges(listener: () => void): () => void {
43
+ authSessionListeners.add(listener);
44
+ return () => {
45
+ authSessionListeners.delete(listener);
46
+ };
47
+ }
48
+
49
+ export function getStoredAuthSession(): AuthSession | null {
50
+ if (memorySession) {
51
+ if (isAuthSessionExpired(memorySession)) {
52
+ clearStoredAuthSession();
53
+ return null;
54
+ }
55
+
56
+ return memorySession;
57
+ }
58
+
59
+ const stored = readLocalStorage(AUTH_SESSION_STORAGE_KEY);
60
+ if (!stored) {
61
+ return null;
62
+ }
63
+
64
+ const parsed = parseStoredAuthSession(stored);
65
+ if (!parsed) {
66
+ clearStoredAuthSession();
67
+ return null;
68
+ }
69
+
70
+ if (isAuthSessionExpired(parsed)) {
71
+ clearStoredAuthSession();
72
+ return null;
73
+ }
74
+
75
+ memorySession = parsed;
76
+ return parsed;
77
+ }
78
+
79
+ export function setStoredAuthSession(session: AuthSession): void {
80
+ const nextSession = normalizeAuthSession(session);
81
+ if (!nextSession) {
82
+ clearStoredAuthSession();
83
+ return;
84
+ }
85
+
86
+ const currentSession = readStoredAuthSessionSnapshot();
87
+ const changed = !areAuthSessionsEqual(currentSession, nextSession);
88
+ memorySession = nextSession;
89
+ writeLocalStorage(AUTH_SESSION_STORAGE_KEY, JSON.stringify(nextSession));
90
+ if (changed) {
91
+ notifyAuthSessionChanged();
92
+ }
93
+ }
94
+
95
+ export function clearStoredAuthSession(): void {
96
+ const hadStoredSession = memorySession !== null || readLocalStorage(AUTH_SESSION_STORAGE_KEY) !== null;
97
+ if (!hadStoredSession) {
98
+ return;
99
+ }
100
+
101
+ memorySession = null;
102
+ removeLocalStorage(AUTH_SESSION_STORAGE_KEY);
103
+ notifyAuthSessionChanged();
104
+ }
105
+
106
+ export function isAuthSessionExpired(session: AuthSession | null | undefined): boolean {
107
+ const expiresAt = session?.expiresAt;
108
+ if (typeof expiresAt !== 'number' || !Number.isFinite(expiresAt)) {
109
+ return false;
110
+ }
111
+
112
+ return expiresAt <= Date.now() + AUTH_EXPIRY_SKEW_MS;
113
+ }
114
+
115
+ export function isAuthenticated(): boolean {
116
+ return getStoredAuthSession() !== null;
117
+ }
118
+
119
+ export function bootstrapAuthSession(): void {
120
+ void getStoredAuthSession();
121
+ }
122
+
123
+ export async function refreshAuthSessionIfNeeded(
124
+ authAdapter: Pick<AuthAdapter, 'refreshSession'>,
125
+ ): Promise<AuthSession | null> {
126
+ const session = getStoredAuthSession();
127
+ if (!session) {
128
+ return null;
129
+ }
130
+
131
+ if (!shouldRefreshAuthSession(session)) {
132
+ return session;
133
+ }
134
+
135
+ if (!authAdapter.refreshSession) {
136
+ return handleRefreshFailure(session);
137
+ }
138
+
139
+ try {
140
+ const result = await authAdapter.refreshSession();
141
+ if (!result.ok) {
142
+ return handleRefreshFailure(session);
143
+ }
144
+
145
+ const nextSession = normalizeAuthSession(result.data);
146
+ if (!nextSession) {
147
+ return handleRefreshFailure(session);
148
+ }
149
+
150
+ setStoredAuthSession(nextSession);
151
+ return nextSession;
152
+ } catch {
153
+ return handleRefreshFailure(session);
154
+ }
155
+ }
156
+
157
+ function handleRefreshFailure(session: AuthSession): AuthSession | null {
158
+ if (isAuthSessionExpired(session)) {
159
+ clearStoredAuthSession();
160
+ return null;
161
+ }
162
+
163
+ return session;
164
+ }
165
+
166
+ function parseStoredAuthSession(raw: string): AuthSession | null {
167
+ try {
168
+ const parsed: unknown = JSON.parse(raw);
169
+ return normalizeAuthSession(parsed);
170
+ } catch {
171
+ return null;
172
+ }
173
+ }
174
+
175
+ function readStoredAuthSessionSnapshot(): AuthSession | null {
176
+ if (memorySession) {
177
+ return memorySession;
178
+ }
179
+
180
+ const stored = readLocalStorage(AUTH_SESSION_STORAGE_KEY);
181
+ if (!stored) {
182
+ return null;
183
+ }
184
+
185
+ return parseStoredAuthSession(stored);
186
+ }
187
+
188
+ function areAuthSessionsEqual(left: AuthSession | null, right: AuthSession | null): boolean {
189
+ if (left === right) {
190
+ return true;
191
+ }
192
+
193
+ if (!left || !right) {
194
+ return false;
195
+ }
196
+
197
+ return JSON.stringify(left) === JSON.stringify(right);
198
+ }
199
+
200
+ function normalizeAuthSession(value: unknown): AuthSession | null {
201
+ if (typeof value !== 'object' || value === null) {
202
+ return null;
203
+ }
204
+
205
+ const accessToken = normalizeRequiredString(Reflect.get(value, 'accessToken'));
206
+ const user = normalizeAuthUser(Reflect.get(value, 'user'));
207
+ if (!accessToken || !user) {
208
+ return null;
209
+ }
210
+
211
+ const refreshToken = normalizeOptionalString(Reflect.get(value, 'refreshToken')) ?? undefined;
212
+ const tokenType = normalizeOptionalString(Reflect.get(value, 'tokenType')) ?? undefined;
213
+ const expiresAt = normalizeOptionalNumber(Reflect.get(value, 'expiresAt')) ?? undefined;
214
+
215
+ return {
216
+ accessToken,
217
+ ...(refreshToken ? { refreshToken } : {}),
218
+ ...(typeof expiresAt === 'number' ? { expiresAt } : {}),
219
+ ...(tokenType ? { tokenType } : {}),
220
+ user,
221
+ };
222
+ }
223
+
224
+ function normalizeAuthUser(value: unknown): AuthUser | null {
225
+ if (typeof value !== 'object' || value === null) {
226
+ return null;
227
+ }
228
+
229
+ const id = normalizeRequiredString(Reflect.get(value, 'id'));
230
+ if (!id) {
231
+ return null;
232
+ }
233
+
234
+ const email = normalizeOptionalString(Reflect.get(value, 'email')) ?? undefined;
235
+ const phone = normalizeOptionalString(Reflect.get(value, 'phone')) ?? undefined;
236
+ const username = normalizeOptionalString(Reflect.get(value, 'username')) ?? undefined;
237
+ const displayName = normalizeOptionalString(Reflect.get(value, 'displayName')) ?? undefined;
238
+ const avatarUrl = normalizeOptionalString(Reflect.get(value, 'avatarUrl')) ?? undefined;
239
+ const metadata = normalizeMetadata(Reflect.get(value, 'metadata'));
240
+
241
+ return {
242
+ id,
243
+ ...(email ? { email } : {}),
244
+ ...(phone ? { phone } : {}),
245
+ ...(username ? { username } : {}),
246
+ ...(displayName ? { displayName } : {}),
247
+ ...(avatarUrl ? { avatarUrl } : {}),
248
+ ...(metadata ? { metadata } : {}),
249
+ };
250
+ }
251
+
252
+ function shouldRefreshAuthSession(session: AuthSession): boolean {
253
+ const { expiresAt } = session;
254
+ if (typeof expiresAt !== 'number' || !Number.isFinite(expiresAt)) {
255
+ return false;
256
+ }
257
+
258
+ return expiresAt - Date.now() <= AUTH_REFRESH_THRESHOLD_MS;
259
+ }
260
+
261
+ function normalizeRequiredString(value: unknown): string | null {
262
+ return typeof value === 'string' && value.length > 0 ? value : null;
263
+ }
264
+
265
+ function normalizeOptionalString(value: unknown): string | null {
266
+ return normalizeRequiredString(value);
267
+ }
268
+
269
+ function normalizeOptionalNumber(value: unknown): number | null {
270
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
271
+ }
272
+
273
+ function normalizeMetadata(value: unknown): Record<string, unknown> | null {
274
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
275
+ return null;
276
+ }
277
+
278
+ const metadata: Record<string, unknown> = {};
279
+ for (const key of Object.keys(value)) {
280
+ metadata[key] = Reflect.get(value, key);
281
+ }
282
+
283
+ return metadata;
284
+ }
285
+
286
+ function getLocalStorage(): AuthStorageLike | null {
287
+ const storage: unknown = Reflect.get(globalThis, 'localStorage');
288
+ return isAuthStorageLike(storage) ? storage : null;
289
+ }
290
+
291
+ function isAuthStorageLike(value: unknown): value is AuthStorageLike {
292
+ return (
293
+ typeof value === 'object' &&
294
+ value !== null &&
295
+ typeof Reflect.get(value, 'getItem') === 'function' &&
296
+ typeof Reflect.get(value, 'setItem') === 'function' &&
297
+ typeof Reflect.get(value, 'removeItem') === 'function'
298
+ );
299
+ }
300
+
301
+ function readLocalStorage(key: string): string | null {
302
+ try {
303
+ return getLocalStorage()?.getItem(key) ?? null;
304
+ } catch {
305
+ return null;
306
+ }
307
+ }
308
+
309
+ function writeLocalStorage(key: string, value: string): void {
310
+ try {
311
+ getLocalStorage()?.setItem(key, value);
312
+ } catch {
313
+ // Best effort only; in-memory session is still set.
314
+ }
315
+ }
316
+
317
+ function removeLocalStorage(key: string): void {
318
+ try {
319
+ getLocalStorage()?.removeItem(key);
320
+ } catch {
321
+ // Best effort only.
322
+ }
323
+ }
324
+ `;
325
+ }
326
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/session.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB;IAC9B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkUR,CAAC;AACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function getSignOutScreenTsx(): string;
2
+ //# sourceMappingURL=signOut.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signOut.d.ts","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/signOut.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,WAyClC"}
@@ -0,0 +1,43 @@
1
+ export function getSignOutScreenTsx() {
2
+ return `import { useZoraTheme } from '@ankhorage/zora';
3
+ import { Stack } from 'expo-router';
4
+ import { useEffect } from 'react';
5
+ import { ActivityIndicator, View } from 'react-native';
6
+
7
+ import { authAdapter } from '@/auth/adapter';
8
+ import { clearStoredAuthSession } from '@/auth/session';
9
+
10
+ const signOutScreenOptions = {
11
+ title: 'Signing out',
12
+ };
13
+
14
+ export default function SignOutScreen() {
15
+ const { theme } = useZoraTheme();
16
+
17
+ useEffect(() => {
18
+ void (async () => {
19
+ try {
20
+ await authAdapter.signOut();
21
+ } finally {
22
+ clearStoredAuthSession();
23
+ }
24
+ })();
25
+ }, []);
26
+
27
+ return (
28
+ <View
29
+ style={{
30
+ flex: 1,
31
+ alignItems: 'center',
32
+ justifyContent: 'center',
33
+ backgroundColor: theme.colors.background,
34
+ }}
35
+ >
36
+ <Stack.Screen options={signOutScreenOptions} />
37
+ <ActivityIndicator color={theme.colors.primary} />
38
+ </View>
39
+ );
40
+ }
41
+ `;
42
+ }
43
+ //# sourceMappingURL=signOut.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signOut.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/signOut.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB;IACjC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCR,CAAC;AACF,CAAC"}
@@ -0,0 +1,11 @@
1
+ export { getRootLayoutTsx } from './rootLayout';
2
+ export { getNestedLayoutTsx } from './nestedLayout';
3
+ export { getScreenTsx } from './screen';
4
+ export { buildNavigatorJsx } from './navigation';
5
+ export type { BuiltNavigatorJsx } from './navigation';
6
+ export { getAuthSessionTs } from './auth/session';
7
+ export { getSignOutScreenTsx } from './auth/signOut';
8
+ export { getAuthAdapterTs } from './auth/adapter';
9
+ export { getAuthScreenTsx } from './auth/screen';
10
+ export { getIndexRedirectRouteTsx } from './redirect';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/host/layout/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,10 @@
1
+ export { getRootLayoutTsx } from './rootLayout';
2
+ export { getNestedLayoutTsx } from './nestedLayout';
3
+ export { getScreenTsx } from './screen';
4
+ export { buildNavigatorJsx } from './navigation';
5
+ export { getAuthSessionTs } from './auth/session';
6
+ export { getSignOutScreenTsx } from './auth/signOut';
7
+ export { getAuthAdapterTs } from './auth/adapter';
8
+ export { getAuthScreenTsx } from './auth/screen';
9
+ export { getIndexRedirectRouteTsx } from './redirect';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/host/layout/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { AppManifest, NavigatorSpec } from '@ankhorage/contracts';
2
+ export interface BuiltNavigatorJsx {
3
+ declarations: string;
4
+ jsx: string;
5
+ usesTheme: boolean;
6
+ usesIcon: boolean;
7
+ usesZoraTabBar: boolean;
8
+ usesZoraDrawerContent: boolean;
9
+ usesZoraNavigationRouteMap: boolean;
10
+ }
11
+ export declare function buildNavigatorJsx(args: {
12
+ navigator: NavigatorSpec;
13
+ manifest: AppManifest;
14
+ includeStudio: boolean;
15
+ }): BuiltNavigatorJsx;
16
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../src/host/layout/templates/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAmB,MAAM,sBAAsB,CAAC;AAIxF,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,0BAA0B,EAAE,OAAO,CAAC;CACrC;AAuCD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,WAAW,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,iBAAiB,CAYpB"}