@nlabs/metropolisjs 0.1.2 → 0.2.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 (329) hide show
  1. package/.github/copilot-instructions.md +167 -0
  2. package/AGENTS.md +13 -0
  3. package/CHANGELOG.md +112 -0
  4. package/GRAPHQL_VALIDATION_RESULTS.md +158 -0
  5. package/PERMISSION_GRAPHQL_INTEGRATION.md +293 -0
  6. package/PERMISSION_IMPLEMENTATION_SUMMARY.md +243 -0
  7. package/README.md +1123 -112
  8. package/SIGNIN_GRAPHQL_VALIDATION.md +125 -0
  9. package/VAULT_GRAPHQL_API_FINDINGS.md +312 -0
  10. package/docs/ACTIONS.md +63 -0
  11. package/docs/COLLECTIONS.md +1038 -0
  12. package/docs/CONNECTIONS.md +1367 -0
  13. package/docs/CRUD_INTEGRATION.md +702 -0
  14. package/examples/connections-usage.tsx +909 -0
  15. package/examples/content-actions-usage.ts +144 -0
  16. package/examples/crud-usage.tsx +847 -0
  17. package/examples/extensibility-usage.tsx +889 -0
  18. package/examples/i18n-import-examples.ts +86 -0
  19. package/examples/i18n-namespace-usage.ts +118 -0
  20. package/examples/i18next-singleton-demo.ts +187 -0
  21. package/examples/permission-system-usage.tsx +415 -0
  22. package/examples/project-details.tsx +397 -0
  23. package/examples/shared-i18n-usage.tsx +203 -0
  24. package/examples/signup-error-handling.ts +100 -0
  25. package/examples/translation-types.ts +86 -0
  26. package/examples/translation-usage.tsx +336 -0
  27. package/index.js +1 -0
  28. package/jest.config.mjs +28 -0
  29. package/lex.config.mjs +11 -2
  30. package/lib/__tests__/e2e/helpers/testGraphQLServer.d.ts +22 -0
  31. package/lib/__tests__/e2e/helpers/testGraphQLServer.d.ts.map +1 -0
  32. package/lib/__tests__/e2e/helpers/testGraphQLServer.js +197 -0
  33. package/lib/__tests__/e2e/helpers/testGraphQLServerSimple.d.ts +3 -0
  34. package/lib/__tests__/e2e/helpers/testGraphQLServerSimple.d.ts.map +1 -0
  35. package/lib/__tests__/e2e/helpers/testGraphQLServerSimple.js +52 -0
  36. package/lib/actions/appActions/appActions.d.ts +29 -0
  37. package/lib/actions/appActions/appActions.d.ts.map +1 -0
  38. package/lib/actions/appActions/appActions.js +159 -0
  39. package/lib/actions/connectionActions/connectionActions.d.ts +19 -0
  40. package/lib/actions/connectionActions/connectionActions.d.ts.map +1 -0
  41. package/lib/actions/connectionActions/connectionActions.js +131 -0
  42. package/lib/actions/contentActions/contentActions.d.ts +34 -0
  43. package/lib/actions/contentActions/contentActions.d.ts.map +1 -0
  44. package/lib/actions/contentActions/contentActions.js +314 -0
  45. package/lib/actions/conversationActions/conversationActions.d.ts +30 -0
  46. package/lib/actions/conversationActions/conversationActions.d.ts.map +1 -0
  47. package/lib/actions/conversationActions/conversationActions.js +225 -0
  48. package/lib/actions/eventActions/eventActions.d.ts +27 -7
  49. package/lib/actions/eventActions/eventActions.d.ts.map +1 -0
  50. package/lib/actions/eventActions/eventActions.js +436 -2
  51. package/lib/actions/groupActions/groupActions.d.ts +30 -0
  52. package/lib/actions/groupActions/groupActions.d.ts.map +1 -0
  53. package/lib/actions/groupActions/groupActions.js +229 -0
  54. package/lib/actions/imageActions/imageActions.d.ts +16 -10
  55. package/lib/actions/imageActions/imageActions.d.ts.map +1 -0
  56. package/lib/actions/imageActions/imageActions.js +593 -2
  57. package/lib/actions/index.d.ts +21 -9
  58. package/lib/actions/index.d.ts.map +1 -0
  59. package/lib/actions/index.js +22 -2
  60. package/lib/actions/locationActions/locationActions.d.ts +11 -9
  61. package/lib/actions/locationActions/locationActions.d.ts.map +1 -0
  62. package/lib/actions/locationActions/locationActions.js +388 -2
  63. package/lib/actions/messageActions/messageActions.d.ts +16 -32
  64. package/lib/actions/messageActions/messageActions.d.ts.map +1 -0
  65. package/lib/actions/messageActions/messageActions.js +235 -2
  66. package/lib/actions/permissionActions/permissionActions.d.ts +34 -0
  67. package/lib/actions/permissionActions/permissionActions.d.ts.map +1 -0
  68. package/lib/actions/permissionActions/permissionActions.js +330 -0
  69. package/lib/actions/personaActions/personaActions.d.ts +65 -0
  70. package/lib/actions/personaActions/personaActions.d.ts.map +1 -0
  71. package/lib/actions/personaActions/personaActions.js +572 -0
  72. package/lib/actions/postActions/postActions.d.ts +12 -32
  73. package/lib/actions/postActions/postActions.d.ts.map +1 -0
  74. package/lib/actions/postActions/postActions.js +447 -2
  75. package/lib/actions/reactionActions/reactionActions.d.ts +13 -27
  76. package/lib/actions/reactionActions/reactionActions.d.ts.map +1 -0
  77. package/lib/actions/reactionActions/reactionActions.js +413 -2
  78. package/lib/actions/sseActions/sseActions.d.ts +1 -0
  79. package/lib/actions/sseActions/sseActions.d.ts.map +1 -0
  80. package/lib/actions/sseActions/sseActions.js +148 -2
  81. package/lib/actions/subscriptionActions/subscriptionActions.d.ts +24 -0
  82. package/lib/actions/subscriptionActions/subscriptionActions.d.ts.map +1 -0
  83. package/lib/actions/subscriptionActions/subscriptionActions.js +329 -0
  84. package/lib/actions/tagActions/tagActions.d.ts +13 -31
  85. package/lib/actions/tagActions/tagActions.d.ts.map +1 -0
  86. package/lib/actions/tagActions/tagActions.js +347 -2
  87. package/lib/actions/translationActions/translationActions.d.ts +38 -0
  88. package/lib/actions/translationActions/translationActions.d.ts.map +1 -0
  89. package/lib/actions/translationActions/translationActions.js +189 -0
  90. package/lib/actions/userActions/userActions.d.ts +42 -95
  91. package/lib/actions/userActions/userActions.d.ts.map +1 -0
  92. package/lib/actions/userActions/userActions.js +844 -2
  93. package/lib/actions/videoActions/videoActions.d.ts +41 -0
  94. package/lib/actions/videoActions/videoActions.d.ts.map +1 -0
  95. package/lib/actions/videoActions/videoActions.js +532 -0
  96. package/lib/actions/websocketActions/websocketActions.d.ts +20 -21
  97. package/lib/actions/websocketActions/websocketActions.d.ts.map +1 -0
  98. package/lib/actions/websocketActions/websocketActions.js +377 -2
  99. package/lib/adapters/appAdapter/appAdapter.d.ts +8 -0
  100. package/lib/adapters/appAdapter/appAdapter.d.ts.map +1 -0
  101. package/lib/adapters/appAdapter/appAdapter.js +90 -0
  102. package/lib/adapters/arangoAdapter/arangoAdapter.d.ts +3 -2
  103. package/lib/adapters/arangoAdapter/arangoAdapter.d.ts.map +1 -0
  104. package/lib/adapters/arangoAdapter/arangoAdapter.js +75 -2
  105. package/lib/adapters/contentAdapter/contentAdapter.d.ts +3 -2
  106. package/lib/adapters/contentAdapter/contentAdapter.d.ts.map +1 -0
  107. package/lib/adapters/contentAdapter/contentAdapter.js +107 -2
  108. package/lib/adapters/conversationAdapter/conversationAdapter.d.ts +3 -2
  109. package/lib/adapters/conversationAdapter/conversationAdapter.d.ts.map +1 -0
  110. package/lib/adapters/conversationAdapter/conversationAdapter.js +75 -2
  111. package/lib/adapters/eventAdapter/eventAdapter.d.ts +5 -2
  112. package/lib/adapters/eventAdapter/eventAdapter.d.ts.map +1 -0
  113. package/lib/adapters/eventAdapter/eventAdapter.js +162 -2
  114. package/lib/adapters/fileAdapter/fileAdapter.d.ts +3 -2
  115. package/lib/adapters/fileAdapter/fileAdapter.d.ts.map +1 -0
  116. package/lib/adapters/fileAdapter/fileAdapter.js +118 -2
  117. package/lib/adapters/groupAdapter/groupAdapter.d.ts +28 -0
  118. package/lib/adapters/groupAdapter/groupAdapter.d.ts.map +1 -0
  119. package/lib/adapters/groupAdapter/groupAdapter.js +66 -0
  120. package/lib/adapters/imageAdapter/imageAdapter.d.ts +9 -2
  121. package/lib/adapters/imageAdapter/imageAdapter.d.ts.map +1 -0
  122. package/lib/adapters/imageAdapter/imageAdapter.js +134 -2
  123. package/lib/adapters/index.d.ts +34 -16
  124. package/lib/adapters/index.d.ts.map +1 -0
  125. package/lib/adapters/index.js +19 -2
  126. package/lib/adapters/locationAdapter/locationAdapter.d.ts +3 -2
  127. package/lib/adapters/locationAdapter/locationAdapter.d.ts.map +1 -0
  128. package/lib/adapters/locationAdapter/locationAdapter.js +95 -2
  129. package/lib/adapters/messageAdapter/messageAdapter.d.ts +23 -19
  130. package/lib/adapters/messageAdapter/messageAdapter.d.ts.map +1 -0
  131. package/lib/adapters/messageAdapter/messageAdapter.js +82 -2
  132. package/lib/adapters/permissionAdapter/permissionAdapter.d.ts +41 -0
  133. package/lib/adapters/permissionAdapter/permissionAdapter.d.ts.map +1 -0
  134. package/lib/adapters/permissionAdapter/permissionAdapter.js +120 -0
  135. package/lib/adapters/personaAdapter/personaAdapter.d.ts +28 -2
  136. package/lib/adapters/personaAdapter/personaAdapter.d.ts.map +1 -0
  137. package/lib/adapters/personaAdapter/personaAdapter.js +161 -2
  138. package/lib/adapters/postAdapter/postAdapter.d.ts +3 -2
  139. package/lib/adapters/postAdapter/postAdapter.d.ts.map +1 -0
  140. package/lib/adapters/postAdapter/postAdapter.js +115 -2
  141. package/lib/adapters/reactionAdapter/reactionAdapter.d.ts +5 -2
  142. package/lib/adapters/reactionAdapter/reactionAdapter.d.ts.map +1 -0
  143. package/lib/adapters/reactionAdapter/reactionAdapter.js +81 -2
  144. package/lib/adapters/reaktorAdapter/reaktorAdapter.d.ts +3 -2
  145. package/lib/adapters/reaktorAdapter/reaktorAdapter.d.ts.map +1 -0
  146. package/lib/adapters/reaktorAdapter/reaktorAdapter.js +58 -2
  147. package/lib/adapters/sessionAdapter/sessionAdapter.d.ts +3 -2
  148. package/lib/adapters/sessionAdapter/sessionAdapter.d.ts.map +1 -0
  149. package/lib/adapters/sessionAdapter/sessionAdapter.js +80 -2
  150. package/lib/adapters/tagAdapter/tagAdapter.d.ts +3 -2
  151. package/lib/adapters/tagAdapter/tagAdapter.d.ts.map +1 -0
  152. package/lib/adapters/tagAdapter/tagAdapter.js +98 -2
  153. package/lib/adapters/translationAdapter/translationAdapter.d.ts +21 -0
  154. package/lib/adapters/translationAdapter/translationAdapter.d.ts.map +1 -0
  155. package/lib/adapters/translationAdapter/translationAdapter.js +55 -0
  156. package/lib/adapters/userAdapter/userAdapter.d.ts +18 -6
  157. package/lib/adapters/userAdapter/userAdapter.d.ts.map +1 -0
  158. package/lib/adapters/userAdapter/userAdapter.js +302 -2
  159. package/lib/adapters/videoAdapter/videoAdapter.d.ts +8 -0
  160. package/lib/adapters/videoAdapter/videoAdapter.d.ts.map +1 -0
  161. package/lib/adapters/videoAdapter/videoAdapter.js +194 -0
  162. package/lib/config/index.d.ts +19 -6
  163. package/lib/config/index.d.ts.map +1 -0
  164. package/lib/config/index.js +97 -2
  165. package/lib/constants/Collections.d.ts +44 -0
  166. package/lib/constants/Collections.d.ts.map +1 -0
  167. package/lib/constants/Collections.js +40 -0
  168. package/lib/constants/MetropolisConstants.d.ts +1 -0
  169. package/lib/constants/MetropolisConstants.d.ts.map +1 -0
  170. package/lib/constants/MetropolisConstants.js +15 -2
  171. package/lib/graphql/message.d.ts +1 -0
  172. package/lib/graphql/message.d.ts.map +1 -0
  173. package/lib/graphql/message.js +6 -4
  174. package/lib/graphql/notification.d.ts +1 -0
  175. package/lib/graphql/notification.d.ts.map +1 -0
  176. package/lib/graphql/notification.js +6 -4
  177. package/lib/graphql/session.d.ts +1 -0
  178. package/lib/graphql/session.d.ts.map +1 -0
  179. package/lib/graphql/session.js +4 -3
  180. package/lib/index.d.ts +45 -22
  181. package/lib/index.d.ts.map +1 -0
  182. package/lib/index.js +248 -2
  183. package/lib/stores/appStore.d.ts +1 -0
  184. package/lib/stores/appStore.d.ts.map +1 -0
  185. package/lib/stores/appStore.js +23 -2
  186. package/lib/stores/contentStore.d.ts +36 -0
  187. package/lib/stores/contentStore.d.ts.map +1 -0
  188. package/lib/stores/contentStore.js +139 -0
  189. package/lib/stores/conversationStore.d.ts +38 -0
  190. package/lib/stores/conversationStore.d.ts.map +1 -0
  191. package/lib/stores/conversationStore.js +117 -0
  192. package/lib/stores/eventStore.d.ts +4 -1
  193. package/lib/stores/eventStore.d.ts.map +1 -0
  194. package/lib/stores/eventStore.js +47 -2
  195. package/lib/stores/groupStore.d.ts +37 -0
  196. package/lib/stores/groupStore.d.ts.map +1 -0
  197. package/lib/stores/groupStore.js +68 -0
  198. package/lib/stores/imageStore.d.ts +6 -1
  199. package/lib/stores/imageStore.d.ts.map +1 -0
  200. package/lib/stores/imageStore.js +53 -2
  201. package/lib/stores/index.d.ts +20 -11
  202. package/lib/stores/index.d.ts.map +1 -0
  203. package/lib/stores/index.js +24 -2
  204. package/lib/stores/locationStore.d.ts +2 -1
  205. package/lib/stores/locationStore.d.ts.map +1 -0
  206. package/lib/stores/locationStore.js +42 -2
  207. package/lib/stores/messageStore.d.ts +19 -4
  208. package/lib/stores/messageStore.d.ts.map +1 -0
  209. package/lib/stores/messageStore.js +137 -2
  210. package/lib/stores/notificationStore.d.ts +33 -0
  211. package/lib/stores/notificationStore.d.ts.map +1 -0
  212. package/lib/stores/notificationStore.js +55 -0
  213. package/lib/stores/permissionStore.d.ts +37 -0
  214. package/lib/stores/permissionStore.d.ts.map +1 -0
  215. package/lib/stores/permissionStore.js +117 -0
  216. package/lib/stores/personaStore.d.ts +26 -0
  217. package/lib/stores/personaStore.d.ts.map +1 -0
  218. package/lib/stores/personaStore.js +118 -0
  219. package/lib/stores/postStore.d.ts +2 -1
  220. package/lib/stores/postStore.d.ts.map +1 -0
  221. package/lib/stores/postStore.js +53 -2
  222. package/lib/stores/reactionStore.d.ts +1 -0
  223. package/lib/stores/reactionStore.d.ts.map +1 -0
  224. package/lib/stores/reactionStore.js +28 -2
  225. package/lib/stores/subscriptionStore.d.ts +41 -0
  226. package/lib/stores/subscriptionStore.d.ts.map +1 -0
  227. package/lib/stores/subscriptionStore.js +85 -0
  228. package/lib/stores/tagStore.d.ts +8 -5
  229. package/lib/stores/tagStore.d.ts.map +1 -0
  230. package/lib/stores/tagStore.js +87 -2
  231. package/lib/stores/translationStore.d.ts +42 -0
  232. package/lib/stores/translationStore.d.ts.map +1 -0
  233. package/lib/stores/translationStore.js +122 -0
  234. package/lib/stores/userStore.d.ts +5 -4
  235. package/lib/stores/userStore.d.ts.map +1 -0
  236. package/lib/stores/userStore.js +319 -2
  237. package/lib/stores/videoStore.d.ts +39 -0
  238. package/lib/stores/videoStore.d.ts.map +1 -0
  239. package/lib/stores/videoStore.js +132 -0
  240. package/lib/stores/websocketStore.d.ts +1 -0
  241. package/lib/stores/websocketStore.d.ts.map +1 -0
  242. package/lib/stores/websocketStore.js +51 -2
  243. package/lib/types/apps.types.d.ts +17 -0
  244. package/lib/types/apps.types.d.ts.map +1 -0
  245. package/lib/types/apps.types.js +6 -0
  246. package/lib/types/common.types.d.ts +31 -0
  247. package/lib/types/common.types.d.ts.map +1 -0
  248. package/lib/types/common.types.js +6 -0
  249. package/lib/types/conversations.types.d.ts +17 -0
  250. package/lib/types/conversations.types.d.ts.map +1 -0
  251. package/lib/types/conversations.types.js +6 -0
  252. package/lib/types/edges.types.d.ts +38 -0
  253. package/lib/types/edges.types.d.ts.map +1 -0
  254. package/lib/types/edges.types.js +6 -0
  255. package/lib/types/groups.types.d.ts +19 -0
  256. package/lib/types/groups.types.d.ts.map +1 -0
  257. package/lib/types/groups.types.js +6 -0
  258. package/lib/types/index.d.ts +12 -0
  259. package/lib/types/index.d.ts.map +1 -0
  260. package/lib/types/index.js +12 -0
  261. package/lib/types/subscriptions.types.d.ts +32 -0
  262. package/lib/types/subscriptions.types.d.ts.map +1 -0
  263. package/lib/types/subscriptions.types.js +6 -0
  264. package/lib/types/videos.types.d.ts +61 -0
  265. package/lib/types/videos.types.d.ts.map +1 -0
  266. package/lib/types/videos.types.js +6 -0
  267. package/lib/utils/MetropolisProvider.d.ts +39 -15
  268. package/lib/utils/MetropolisProvider.d.ts.map +1 -0
  269. package/lib/utils/MetropolisProvider.js +31 -2
  270. package/lib/utils/actionFactory.d.ts +21 -19
  271. package/lib/utils/actionFactory.d.ts.map +1 -0
  272. package/lib/utils/actionFactory.js +95 -2
  273. package/lib/utils/api.d.ts +5 -4
  274. package/lib/utils/api.d.ts.map +1 -0
  275. package/lib/utils/api.js +252 -6
  276. package/lib/utils/app.d.ts +1 -0
  277. package/lib/utils/app.d.ts.map +1 -0
  278. package/lib/utils/app.js +15 -2
  279. package/lib/utils/baseActionFactory.d.ts +5 -23
  280. package/lib/utils/baseActionFactory.d.ts.map +1 -0
  281. package/lib/utils/baseActionFactory.js +72 -2
  282. package/lib/utils/configUtils.d.ts +11 -0
  283. package/lib/utils/configUtils.d.ts.map +1 -0
  284. package/lib/utils/configUtils.js +20 -0
  285. package/lib/utils/dateUtils.d.ts +1 -0
  286. package/lib/utils/dateUtils.d.ts.map +1 -0
  287. package/lib/utils/dateUtils.js +11 -2
  288. package/lib/utils/file.d.ts +3 -1
  289. package/lib/utils/file.d.ts.map +1 -0
  290. package/lib/utils/file.js +156 -2
  291. package/lib/utils/i18n.d.ts +7 -0
  292. package/lib/utils/i18n.d.ts.map +1 -0
  293. package/lib/utils/i18n.js +96 -0
  294. package/lib/utils/index.d.ts +20 -0
  295. package/lib/utils/index.d.ts.map +1 -0
  296. package/lib/utils/index.js +26 -0
  297. package/lib/utils/location.d.ts +4 -3
  298. package/lib/utils/location.d.ts.map +1 -0
  299. package/lib/utils/location.js +82 -2
  300. package/lib/utils/permissionUtils.d.ts +22 -0
  301. package/lib/utils/permissionUtils.d.ts.map +1 -0
  302. package/lib/utils/permissionUtils.js +72 -0
  303. package/lib/utils/requestCache.d.ts +8 -0
  304. package/lib/utils/requestCache.d.ts.map +1 -0
  305. package/lib/utils/requestCache.js +53 -0
  306. package/lib/utils/session.d.ts +14 -0
  307. package/lib/utils/session.d.ts.map +1 -0
  308. package/lib/utils/session.js +107 -0
  309. package/lib/utils/useConversationTyping.d.ts +26 -0
  310. package/lib/utils/useConversationTyping.d.ts.map +1 -0
  311. package/lib/utils/useConversationTyping.js +117 -0
  312. package/lib/utils/useMetropolis.d.ts +67 -12
  313. package/lib/utils/useMetropolis.d.ts.map +1 -0
  314. package/lib/utils/useMetropolis.js +311 -2
  315. package/lib/utils/useTranslations.d.ts +16 -0
  316. package/lib/utils/useTranslations.d.ts.map +1 -0
  317. package/lib/utils/useTranslations.js +105 -0
  318. package/lib/utils/validatorFactory.d.ts +3 -2
  319. package/lib/utils/validatorFactory.d.ts.map +1 -0
  320. package/lib/utils/validatorFactory.js +95 -2
  321. package/package.json +58 -17
  322. package/temp_signin.ts +73 -0
  323. package/lib/actions/profileActions/profileActions.d.ts +0 -50
  324. package/lib/actions/profileActions/profileActions.js +0 -2
  325. package/lib/adapters/profileAdapter/profileAdapter.d.ts +0 -32
  326. package/lib/adapters/profileAdapter/profileAdapter.js +0 -2
  327. package/lib/stores/profileStore.d.ts +0 -24
  328. package/lib/stores/profileStore.js +0 -2
  329. /package/{FACTORY_PATTERN_GUIDE.md → factoryPatternGuide.md} +0 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Copyright (c) 2025-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */
5
+
6
+ // Define the types directly to avoid JSX compilation issues
7
+ type SimpleTranslations = Record<string, string>;
8
+
9
+ interface ComplexTranslation {
10
+ readonly value: string;
11
+ readonly locale: string;
12
+ readonly namespace?: string;
13
+ }
14
+
15
+ type ComplexTranslations = Record<string, ComplexTranslation>;
16
+
17
+ // Test simple translations type
18
+ const simpleTranslations: SimpleTranslations = {
19
+ 'welcome': 'Welcome to MetropolisJS!',
20
+ 'hello': 'Hello {{name}}!',
21
+ 'goodbye': 'Goodbye'
22
+ };
23
+
24
+ // Test complex translations type
25
+ const complexTranslations: ComplexTranslations = {
26
+ 'welcome:en': {
27
+ value: 'Welcome to MetropolisJS!',
28
+ locale: 'en',
29
+ namespace: 'common'
30
+ },
31
+ 'hello:en': {
32
+ value: 'Hello {{name}}!',
33
+ locale: 'en',
34
+ namespace: 'common'
35
+ },
36
+ 'save:en': {
37
+ value: 'Save',
38
+ locale: 'en',
39
+ namespace: 'buttons'
40
+ }
41
+ };
42
+
43
+ // Test individual complex translation type
44
+ const singleTranslation: ComplexTranslation = {
45
+ value: 'Test translation',
46
+ locale: 'en',
47
+ namespace: 'test'
48
+ };
49
+
50
+ // Function to demonstrate type safety
51
+ function processTranslations(translations: SimpleTranslations | ComplexTranslations): void {
52
+ if (Object.keys(translations).length === 0) {
53
+ console.log('No translations provided');
54
+ return;
55
+ }
56
+
57
+ const firstKey = Object.keys(translations)[0];
58
+ const firstValue = translations[firstKey];
59
+
60
+ if (typeof firstValue === 'string') {
61
+ // TypeScript knows this is SimpleTranslations
62
+ console.log('Processing simple translations');
63
+ Object.entries(translations as SimpleTranslations).forEach(([key, value]) => {
64
+ console.log(`${key}: ${value}`);
65
+ });
66
+ } else if (typeof firstValue === 'object' && firstValue !== null && 'value' in firstValue) {
67
+ // TypeScript knows this is ComplexTranslations
68
+ console.log('Processing complex translations');
69
+ Object.entries(translations as ComplexTranslations).forEach(([key, translation]) => {
70
+ console.log(`${key}: ${translation.value} (${translation.locale}${translation.namespace ? `, ${translation.namespace}` : ''})`);
71
+ });
72
+ }
73
+ }
74
+
75
+ // Test the function with both types
76
+ console.log('Testing simple translations:');
77
+ processTranslations(simpleTranslations);
78
+
79
+ console.log('\nTesting complex translations:');
80
+ processTranslations(complexTranslations);
81
+
82
+ console.log('\nType test completed successfully!');
83
+
84
+ // Export for use in other files
85
+ export { complexTranslations, processTranslations, simpleTranslations, singleTranslation };
86
+ export type { ComplexTranslation, ComplexTranslations, SimpleTranslations };
@@ -0,0 +1,336 @@
1
+ /**
2
+ * Copyright (c) 2025-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */
5
+
6
+ import React from 'react';
7
+ import { ComplexTranslations, Metropolis, SimpleTranslations } from '../src/index';
8
+ import { i18n } from '../src/utils/i18n';
9
+
10
+ // Example translations object with simple key-value pairs
11
+ const simpleTranslations: SimpleTranslations = {
12
+ 'welcome': 'Welcome to MetropolisJS!',
13
+ 'hello': 'Hello {{name}}!',
14
+ 'goodbye': 'Goodbye',
15
+ 'loading': 'Loading...',
16
+ 'error': 'An error occurred',
17
+ 'success': 'Operation completed successfully',
18
+ 'cancel': 'Cancel',
19
+ 'save': 'Save',
20
+ 'delete': 'Delete',
21
+ 'edit': 'Edit',
22
+ 'create': 'Create',
23
+ 'update': 'Update',
24
+ 'search': 'Search',
25
+ 'filter': 'Filter',
26
+ 'sort': 'Sort',
27
+ 'refresh': 'Refresh',
28
+ 'back': 'Back',
29
+ 'next': 'Next',
30
+ 'previous': 'Previous',
31
+ 'submit': 'Submit',
32
+ 'reset': 'Reset',
33
+ 'confirm': 'Confirm',
34
+ 'yes': 'Yes',
35
+ 'no': 'No',
36
+ 'ok': 'OK',
37
+ 'close': 'Close',
38
+ 'open': 'Open',
39
+ 'show': 'Show',
40
+ 'hide': 'Hide',
41
+ 'expand': 'Expand',
42
+ 'collapse': 'Collapse',
43
+ 'minimize': 'Minimize',
44
+ 'maximize': 'Maximize',
45
+ 'fullscreen': 'Fullscreen',
46
+ 'settings': 'Settings',
47
+ 'profile': 'Profile',
48
+ 'account': 'Account',
49
+ 'logout': 'Logout',
50
+ 'login': 'Login',
51
+ 'register': 'Register',
52
+ 'forgot_password': 'Forgot Password?',
53
+ 'remember_me': 'Remember Me',
54
+ 'email': 'Email',
55
+ 'password': 'Password',
56
+ 'username': 'Username',
57
+ 'first_name': 'First Name',
58
+ 'last_name': 'Last Name',
59
+ 'phone': 'Phone',
60
+ 'address': 'Address',
61
+ 'city': 'City',
62
+ 'state': 'State',
63
+ 'country': 'Country',
64
+ 'zip_code': 'ZIP Code',
65
+ 'birth_date': 'Birth Date',
66
+ 'gender': 'Gender',
67
+ 'male': 'Male',
68
+ 'female': 'Female',
69
+ 'other': 'Other',
70
+ 'prefer_not_to_say': 'Prefer not to say'
71
+ };
72
+
73
+ // Example complex translations with locale and namespace support
74
+ const complexTranslations: ComplexTranslations = {
75
+ 'welcome:en': {
76
+ value: 'Welcome to MetropolisJS!',
77
+ locale: 'en',
78
+ namespace: 'common'
79
+ },
80
+ 'hello:en': {
81
+ value: 'Hello {{name}}!',
82
+ locale: 'en',
83
+ namespace: 'common'
84
+ },
85
+ 'save:en': {
86
+ value: 'Save',
87
+ locale: 'en',
88
+ namespace: 'buttons'
89
+ },
90
+ 'cancel:en': {
91
+ value: 'Cancel',
92
+ locale: 'en',
93
+ namespace: 'buttons'
94
+ },
95
+ 'welcome:es': {
96
+ value: '¡Bienvenido a MetropolisJS!',
97
+ locale: 'es',
98
+ namespace: 'common'
99
+ },
100
+ 'hello:es': {
101
+ value: '¡Hola {{name}}!',
102
+ locale: 'es',
103
+ namespace: 'common'
104
+ },
105
+ 'save:es': {
106
+ value: 'Guardar',
107
+ locale: 'es',
108
+ namespace: 'buttons'
109
+ }
110
+ };
111
+
112
+ // Example React component using Metropolis with simple translations
113
+ const SimpleTranslationApp: React.FC = () => {
114
+ return (
115
+ <Metropolis
116
+ translations={simpleTranslations}
117
+ config={{
118
+ development: {
119
+ app: {
120
+ api: {
121
+ url: 'https://api.example.com'
122
+ },
123
+ urls: {
124
+ websocket: 'wss://ws.example.com'
125
+ }
126
+ }
127
+ }
128
+ }}
129
+ >
130
+ <div>
131
+ <h1>{i18n('welcome')}</h1>
132
+ <p>{i18n('hello', {name: 'John'})}</p>
133
+ <button>{i18n('save')}</button>
134
+ <button>{i18n('cancel')}</button>
135
+ <p>{i18n('loading')}</p>
136
+ </div>
137
+ </Metropolis>
138
+ );
139
+ };
140
+
141
+ // Example React component using Metropolis with complex translations
142
+ const ComplexTranslationApp: React.FC = () => {
143
+ return (
144
+ <Metropolis
145
+ translations={complexTranslations}
146
+ config={{
147
+ development: {
148
+ app: {
149
+ api: {
150
+ url: 'https://api.example.com'
151
+ },
152
+ urls: {
153
+ websocket: 'wss://ws.example.com'
154
+ }
155
+ }
156
+ }
157
+ }}
158
+ >
159
+ <div>
160
+ <h1>{i18n('welcome', {}, 'en', 'common')}</h1>
161
+ <p>{i18n('hello', {name: 'John'}, 'en', 'common')}</p>
162
+ <button>{i18n('save', {}, 'en', 'buttons')}</button>
163
+ <button>{i18n('cancel', {}, 'en', 'buttons')}</button>
164
+ <p>{i18n('loading')}</p>
165
+ </div>
166
+ </Metropolis>
167
+ );
168
+ };
169
+
170
+ // Example of using translations in a component
171
+ const UserProfile: React.FC = () => {
172
+ const [isLoading, setIsLoading] = React.useState(false);
173
+ const [user, setUser] = React.useState({name: 'John Doe'});
174
+
175
+ return (
176
+ <div>
177
+ <h2>{i18n('profile')}</h2>
178
+ {isLoading ? (
179
+ <p>{i18n('loading')}</p>
180
+ ) : (
181
+ <div>
182
+ <p>{i18n('hello', {name: user.name})}</p>
183
+ <button>{i18n('edit')}</button>
184
+ <button>{i18n('delete')}</button>
185
+ </div>
186
+ )}
187
+ </div>
188
+ );
189
+ };
190
+
191
+ // Example of a form component with translations
192
+ const LoginForm: React.FC = () => {
193
+ const [formData, setFormData] = React.useState({
194
+ email: '',
195
+ password: '',
196
+ rememberMe: false
197
+ });
198
+
199
+ const handleSubmit = (e: React.FormEvent) => {
200
+ e.preventDefault();
201
+ // Handle form submission
202
+ };
203
+
204
+ return (
205
+ <form onSubmit={handleSubmit}>
206
+ <h2>{i18n('login')}</h2>
207
+
208
+ <div>
209
+ <label htmlFor="email">{i18n('email')}:</label>
210
+ <input
211
+ id="email"
212
+ type="email"
213
+ value={formData.email}
214
+ onChange={(e) => setFormData({...formData, email: e.target.value})}
215
+ required
216
+ />
217
+ </div>
218
+
219
+ <div>
220
+ <label htmlFor="password">{i18n('password')}:</label>
221
+ <input
222
+ id="password"
223
+ type="password"
224
+ value={formData.password}
225
+ onChange={(e) => setFormData({...formData, password: e.target.value})}
226
+ required
227
+ />
228
+ </div>
229
+
230
+ <div>
231
+ <label>
232
+ <input
233
+ type="checkbox"
234
+ checked={formData.rememberMe}
235
+ onChange={(e) => setFormData({...formData, rememberMe: e.target.checked})}
236
+ />
237
+ {i18n('remember_me')}
238
+ </label>
239
+ </div>
240
+
241
+ <div>
242
+ <button type="submit">{i18n('login')}</button>
243
+ <button type="button">{i18n('cancel')}</button>
244
+ </div>
245
+
246
+ <div>
247
+ <a href="#forgot-password">{i18n('forgot_password')}</a>
248
+ </div>
249
+ </form>
250
+ );
251
+ };
252
+
253
+ // Example of a multilingual app that can switch between simple and complex translations
254
+ const MultilingualApp: React.FC = () => {
255
+ const [useComplexTranslations, setUseComplexTranslations] = React.useState(false);
256
+ const [currentLocale, setCurrentLocale] = React.useState<'en' | 'es'>('en');
257
+
258
+ const selectedTranslations = useComplexTranslations ? complexTranslations : simpleTranslations;
259
+
260
+ return (
261
+ <Metropolis
262
+ translations={selectedTranslations}
263
+ config={{
264
+ development: {
265
+ app: {
266
+ api: {
267
+ url: 'https://api.example.com'
268
+ },
269
+ urls: {
270
+ websocket: 'wss://ws.example.com'
271
+ }
272
+ }
273
+ }
274
+ }}
275
+ >
276
+ <div>
277
+ <div style={{marginBottom: '20px'}}>
278
+ <label>
279
+ <input
280
+ type="checkbox"
281
+ checked={useComplexTranslations}
282
+ onChange={(e) => setUseComplexTranslations(e.target.checked)}
283
+ />
284
+ Use Complex Translations
285
+ </label>
286
+
287
+ {useComplexTranslations && (
288
+ <div style={{marginLeft: '20px'}}>
289
+ <label>
290
+ Locale:
291
+ <select value={currentLocale} onChange={(e) => setCurrentLocale(e.target.value as 'en' | 'es')}>
292
+ <option value="en">English</option>
293
+ <option value="es">Español</option>
294
+ </select>
295
+ </label>
296
+ </div>
297
+ )}
298
+ </div>
299
+
300
+ <h1>
301
+ {useComplexTranslations
302
+ ? i18n('welcome', {}, currentLocale, 'common')
303
+ : i18n('welcome')
304
+ }
305
+ </h1>
306
+
307
+ <p>
308
+ {useComplexTranslations
309
+ ? i18n('hello', {name: 'World'}, currentLocale, 'common')
310
+ : i18n('hello', {name: 'World'})
311
+ }
312
+ </p>
313
+
314
+ <div>
315
+ <button>
316
+ {useComplexTranslations
317
+ ? i18n('save', {}, currentLocale, 'buttons')
318
+ : i18n('save')
319
+ }
320
+ </button>
321
+ <button>
322
+ {useComplexTranslations
323
+ ? i18n('cancel', {}, currentLocale, 'buttons')
324
+ : i18n('cancel')
325
+ }
326
+ </button>
327
+ </div>
328
+
329
+ <UserProfile />
330
+ <LoginForm />
331
+ </div>
332
+ </Metropolis>
333
+ );
334
+ };
335
+
336
+ export default MultilingualApp;
package/index.js CHANGED
@@ -2,4 +2,5 @@
2
2
  * Copyright (c) 2018-Present, Nitrogen Labs, Inc.
3
3
  * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
4
  */
5
+ export { i18n, initI18n, updateI18nResources } from './src/utils/i18n';
5
6
  module.exports = require('./lib');
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Jest configuration for MetropolisJS tests.
3
+ * Pulls the default Lex Jest config (which includes TS/Babel transforms)
4
+ * and overlays the project-specific settings from lex.config.mjs.
5
+ */
6
+ import lexConfig from './lex.config.mjs';
7
+ import baseConfig from './node_modules/@nlabs/lex/jest.config.mjs';
8
+
9
+ const projectJest = lexConfig?.jest || {};
10
+
11
+ export default {
12
+ ...baseConfig,
13
+ ...projectJest,
14
+ testPathIgnorePatterns: [
15
+ 'lib/__tests__/e2e/helpers/testGraphQLServer.d.ts',
16
+ 'lib/__tests__/e2e/helpers/testGraphQLServerSimple.d.ts'
17
+ ],
18
+ transformIgnorePatterns: [
19
+ '/node_modules/(?!(?:@nlabs/utils|@nlabs/rip-hunter)/)'
20
+ ],
21
+ moduleNameMapper: {
22
+ ...baseConfig.moduleNameMapper,
23
+ ...projectJest.moduleNameMapper
24
+ },
25
+ transform: {
26
+ ...baseConfig.transform
27
+ }
28
+ };
package/lex.config.mjs CHANGED
@@ -1,4 +1,6 @@
1
- export default {
1
+ import {Config} from '@nlabs/lex';
2
+
3
+ export default Config.create({
2
4
  ai: {
3
5
  maxTokens: 4000,
4
6
  model: 'cursor-code',
@@ -6,12 +8,19 @@ export default {
6
8
  temperature: 0.1
7
9
  },
8
10
  entryJS: 'app.tsx',
11
+ esbuild: {
12
+ minify: process.env.NODE_ENV === 'production'
13
+ },
9
14
  gitUrl: 'https://github.com/nitrogenlabs/metropolisjs',
10
15
  jest: {
16
+ extensionsToTreatAsEsm: ['.ts', '.tsx'],
17
+ moduleNameMapper: {
18
+ '^@nlabs/(.*)$': '<rootDir>/node_modules/@nlabs/$1'
19
+ },
11
20
  testEnvironment: 'jsdom'
12
21
  },
13
22
  outputPath: 'lib',
14
23
  targetEnvironment: 'web',
15
24
  useESM: true,
16
25
  useTypescript: true
17
- };
26
+ });
@@ -0,0 +1,22 @@
1
+ export declare const MOCK_USER: {
2
+ userId: string;
3
+ username: string;
4
+ email: string;
5
+ password: string;
6
+ };
7
+ export declare const MOCK_SESSION: {
8
+ token: string;
9
+ expires: number;
10
+ issued: number;
11
+ userId: string;
12
+ username: string;
13
+ };
14
+ /**
15
+ * Start test GraphQL server
16
+ */
17
+ export declare const startTestServer: (port?: number) => Promise<unknown>;
18
+ /**
19
+ * Stop test server
20
+ */
21
+ export declare const stopTestServer: (server: any) => Promise<unknown>;
22
+ //# sourceMappingURL=testGraphQLServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testGraphQLServer.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/e2e/helpers/testGraphQLServer.ts"],"names":[],"mappings":"AA8CA,eAAO,MAAM,SAAS;;;;;CAKrB,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;CAMxB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAU,aAAW,qBA6HhD,CAAC;AAUF;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,WAAM,qBAIpC,CAAC"}