@mr.dj2u/library-registry 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +3 -0
  2. package/assets/mds/env/convex.env.example +1 -0
  3. package/assets/mds/env/firebase.env.example +6 -0
  4. package/assets/mds/env/supabase.env.example +3 -0
  5. package/assets/mds/project/auth-base.md +17 -0
  6. package/assets/mds/project/auth-convex.md +33 -0
  7. package/assets/mds/project/auth-firebase.md +22 -0
  8. package/assets/mds/project/auth-supabase.md +46 -0
  9. package/assets/mds/src/app/(auth)/reset-password.tsx +5 -0
  10. package/assets/mds/src/app/(auth)/sign-in.tsx +5 -0
  11. package/assets/mds/src/app/(auth)/sign-up.tsx +5 -0
  12. package/assets/mds/src/app/legal/updates.tsx +1 -0
  13. package/assets/mds/src/app/onboarding/complete.tsx +2 -0
  14. package/assets/mds/src/app/onboarding/features.tsx +1 -0
  15. package/assets/mds/src/app/onboarding/legal.tsx +2 -0
  16. package/assets/mds/src/app/onboarding.tsx +1 -1
  17. package/assets/mds/src/app/settings.tsx +10 -1
  18. package/assets/mds/src/db/adapter.ts +195 -0
  19. package/assets/mds/src/db/firebase.ts +77 -0
  20. package/assets/mds/src/db/index.firebase.ts +19 -0
  21. package/assets/mds/src/db/index.supabase.ts +22 -0
  22. package/assets/mds/src/db/supabase.ts +337 -0
  23. package/assets/mds/src/features/auth/adapters/base-auth-adapter.tsx +82 -0
  24. package/assets/mds/src/features/auth/adapters/convex-auth-adapter.tsx +156 -0
  25. package/assets/mds/src/features/auth/adapters/firebase-auth-adapter.tsx +147 -0
  26. package/assets/mds/src/features/auth/adapters/supabase-auth-adapter.tsx +166 -0
  27. package/assets/mds/src/features/auth/auth-guard-logic.ts +19 -0
  28. package/assets/mds/src/features/auth/auth-guard.tsx +77 -0
  29. package/assets/mds/src/features/auth/auth-provider.tsx +60 -0
  30. package/assets/mds/src/features/auth/auth-screen.tsx +265 -0
  31. package/assets/mds/src/features/auth/auth-types.ts +45 -0
  32. package/assets/mds/src/features/exposition/data-screen.tsx +4 -2
  33. package/assets/mds/src/features/exposition/expo-sdk-56-screen.tsx +119 -76
  34. package/assets/mds/src/features/exposition/exposition-screen.tsx +10 -11
  35. package/assets/mds/src/features/exposition/stylist-screen.tsx +62 -11
  36. package/assets/mds/src/features/legal/legal-acceptance-adapter.ts +190 -0
  37. package/assets/mds/src/features/legal/legal-acceptance-config.ts +79 -0
  38. package/assets/mds/src/features/legal/legal-agreement-screen.tsx +9 -4
  39. package/assets/mds/src/features/legal/legal-document-modal.tsx +7 -3
  40. package/assets/mds/src/features/legal/legal-document-view.tsx +1 -0
  41. package/assets/mds/src/features/legal/legal-documents.ts +17 -3
  42. package/assets/mds/src/features/legal/legal-update-screen.tsx +297 -0
  43. package/assets/mds/src/features/legal/use-legal-acceptance.ts +1 -38
  44. package/assets/mds/src/features/onboarding/complete-screen.tsx +138 -0
  45. package/assets/mds/src/features/onboarding/features-screen.tsx +129 -0
  46. package/assets/mds/src/features/onboarding/legal-review-screen.tsx +242 -0
  47. package/assets/mds/src/features/onboarding/onboarding-config-with-legal.ts +104 -0
  48. package/assets/mds/src/features/onboarding/onboarding-config.ts +104 -0
  49. package/assets/mds/src/features/onboarding/onboarding-persistence-sync.tsx +1 -0
  50. package/assets/mds/src/features/onboarding/welcome-screen.tsx +130 -0
  51. package/assets/mds/src/features/onboarding-state/adapters/memory-onboarding-state-adapter.ts +15 -0
  52. package/assets/mds/src/features/onboarding-state/adapters/supabase-onboarding-state-adapter.ts +45 -0
  53. package/assets/mds/src/features/onboarding-state/adapters/zustand-onboarding-state-adapter.ts +16 -0
  54. package/assets/mds/src/features/onboarding-state/adapters/zustand-supabase-onboarding-state-adapter.ts +53 -0
  55. package/assets/mds/src/features/onboarding-state/onboarding-state-core.ts +108 -0
  56. package/assets/mds/src/features/onboarding-state/onboarding-state-memory.ts +106 -0
  57. package/assets/mds/src/features/onboarding-state/onboarding-state-supabase.ts +246 -0
  58. package/assets/mds/src/features/onboarding-state/onboarding-state-types.ts +64 -0
  59. package/assets/mds/src/features/onboarding-state/onboarding-state-zustand-supabase.ts +120 -0
  60. package/assets/mds/src/features/onboarding-state/onboarding-state-zustand.ts +71 -0
  61. package/assets/mds/src/features/onboarding-state/onboarding-state.ts +22 -0
  62. package/assets/mds/src/features/onboarding-state/onboarding-store.ts +39 -0
  63. package/assets/mds/src/features/settings/settings-screen-logic.ts +122 -0
  64. package/assets/mds/src/features/settings/settings-screen.tsx +274 -28
  65. package/assets/mds/src/services/convex.ts +40 -0
  66. package/assets/mds/src/services/firebase.ts +70 -0
  67. package/assets/mds/src/services/supabase.ts +50 -0
  68. package/assets/mds/src/theme/color-utils.ts +42 -0
  69. package/assets/mds/src/theme/provider.tsx +15 -5
  70. package/assets/mds/src/types/database.ts +13 -0
  71. package/assets/mds/supabase/migrations/0001_mds_auth_onboarding.sql +107 -0
  72. package/dist/catalog.d.ts.map +1 -1
  73. package/dist/catalog.js +444 -29
  74. package/dist/catalog.js.map +1 -1
  75. package/dist/types.d.ts +5 -1
  76. package/dist/types.d.ts.map +1 -1
  77. package/package.json +1 -1
  78. package/assets/mds/src/app/onboarding/account-setup.tsx +0 -1
  79. package/assets/mds/src/app/onboarding/agreement.tsx +0 -1
  80. package/assets/mds/src/app/onboarding/terms.tsx +0 -1
  81. package/assets/mds/src/features/onboarding/account-setup-screen.tsx +0 -54
  82. package/assets/mds/src/features/onboarding/agreement-screen.tsx +0 -6
  83. package/assets/mds/src/features/onboarding/components/legal-document-view.tsx +0 -103
  84. package/assets/mds/src/features/onboarding/legal-documents.ts +0 -80
  85. package/assets/mds/src/features/onboarding/onboarding-screen.tsx +0 -167
  86. package/assets/mds/src/features/onboarding/terms-screen.tsx +0 -6
@@ -0,0 +1,50 @@
1
+ import AsyncStorage from '@react-native-async-storage/async-storage';
2
+ import { AppState } from 'react-native';
3
+ import { createClient } from '@supabase/supabase-js';
4
+
5
+ const supabaseUrl = process.env.EXPO_PUBLIC_SUPABASE_URL;
6
+ const supabasePublishableKey =
7
+ process.env.EXPO_PUBLIC_SUPABASE_PUBLISHABLE_KEY ??
8
+ process.env.EXPO_PUBLIC_SUPABASE_KEY ??
9
+ process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY;
10
+ const isServerRender = typeof window === 'undefined';
11
+ const supabaseStorage = {
12
+ getItem: (key: string) => (isServerRender ? Promise.resolve(null) : AsyncStorage.getItem(key)),
13
+ setItem: (key: string, value: string) =>
14
+ isServerRender ? Promise.resolve() : AsyncStorage.setItem(key, value),
15
+ removeItem: (key: string) => (isServerRender ? Promise.resolve() : AsyncStorage.removeItem(key)),
16
+ };
17
+ export const supabase =
18
+ supabaseUrl && supabasePublishableKey
19
+ ? createClient(supabaseUrl, supabasePublishableKey, {
20
+ auth: {
21
+ storage: supabaseStorage,
22
+ autoRefreshToken: !isServerRender,
23
+ persistSession: !isServerRender,
24
+ detectSessionInUrl: false,
25
+ },
26
+ })
27
+ : null;
28
+
29
+ if (supabase) {
30
+ AppState.addEventListener('change', (state) => {
31
+ if (state === 'active') {
32
+ supabase.auth.startAutoRefresh();
33
+ } else {
34
+ supabase.auth.stopAutoRefresh();
35
+ }
36
+ });
37
+ }
38
+
39
+ export function getSupabaseClient(): NonNullable<typeof supabase> {
40
+ if (!supabase) {
41
+ throw new Error(
42
+ 'Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_PUBLISHABLE_KEY before using Supabase. EXPO_PUBLIC_SUPABASE_KEY and EXPO_PUBLIC_SUPABASE_ANON_KEY are accepted as fallbacks for older projects.'
43
+ );
44
+ }
45
+ return supabase;
46
+ }
47
+
48
+ export function assertSupabaseConfigured(): void {
49
+ void getSupabaseClient();
50
+ }
@@ -0,0 +1,42 @@
1
+ function parseHexColor(color: string): [number, number, number] | null {
2
+ const normalized = color.trim().replace(/^#/, '');
3
+
4
+ if (/^[0-9a-f]{3}$/i.test(normalized)) {
5
+ return normalized.split('').map((value) => parseInt(`${value}${value}`, 16)) as [
6
+ number,
7
+ number,
8
+ number,
9
+ ];
10
+ }
11
+
12
+ if (/^[0-9a-f]{6}$/i.test(normalized)) {
13
+ return [
14
+ parseInt(normalized.slice(0, 2), 16),
15
+ parseInt(normalized.slice(2, 4), 16),
16
+ parseInt(normalized.slice(4, 6), 16),
17
+ ];
18
+ }
19
+
20
+ return null;
21
+ }
22
+
23
+ function toLinearChannel(value: number): number {
24
+ const channel = value / 255;
25
+ return channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;
26
+ }
27
+
28
+ export function getReadableTextColor(
29
+ backgroundColor: string,
30
+ darkText = '#111827',
31
+ lightText = '#ffffff',
32
+ ): string {
33
+ const rgb = parseHexColor(backgroundColor);
34
+ if (!rgb) {
35
+ return lightText;
36
+ }
37
+
38
+ const [red, green, blue] = rgb.map(toLinearChannel);
39
+ const luminance = 0.2126 * red + 0.7152 * green + 0.0722 * blue;
40
+
41
+ return luminance > 0.45 ? darkText : lightText;
42
+ }
@@ -7,7 +7,7 @@ import {
7
7
  type ReactNode,
8
8
  type SetStateAction,
9
9
  } from 'react';
10
- import { useColorScheme } from 'react-native';
10
+ import { Appearance, useColorScheme } from 'react-native';
11
11
 
12
12
  import defaultThemeTokens, {
13
13
  type StylistColorPalette,
@@ -25,10 +25,17 @@ export type AppThemeColorOverrides = Partial<
25
25
  Record<StylistColorScheme, Partial<StylistColorPalette>>
26
26
  >;
27
27
 
28
+ export function readSystemScheme(): StylistColorScheme | null {
29
+ const scheme = Appearance.getColorScheme();
30
+ return scheme === 'light' || scheme === 'dark' ? scheme : null;
31
+ }
32
+
33
+ const initialSystemScheme = readSystemScheme() ?? 'light';
34
+
28
35
  const AppThemeContext = createContext<AppThemeValue>({
29
36
  ...defaultThemeTokens,
30
- activeScheme: defaultThemeTokens.colorSystem.previewScheme,
31
- activeColors: defaultThemeTokens.colors[defaultThemeTokens.colorSystem.previewScheme],
37
+ activeScheme: initialSystemScheme,
38
+ activeColors: defaultThemeTokens.colors[initialSystemScheme],
32
39
  });
33
40
  const AppThemeSetterContext = createContext<Dispatch<SetStateAction<StylistThemeTokens>> | null>(
34
41
  null
@@ -42,10 +49,13 @@ function resolveActiveScheme(
42
49
  if (preference === 'light' || preference === 'dark') {
43
50
  return preference;
44
51
  }
45
- if (preference === 'system' && (systemScheme === 'light' || systemScheme === 'dark')) {
52
+ if (preference === 'preview') {
53
+ return theme.colorSystem.previewScheme;
54
+ }
55
+ if (systemScheme === 'light' || systemScheme === 'dark') {
46
56
  return systemScheme;
47
57
  }
48
- return theme.colorSystem.previewScheme;
58
+ return readSystemScheme() ?? 'light';
49
59
  }
50
60
 
51
61
  export function AppThemeProvider({
@@ -0,0 +1,13 @@
1
+ import type { DatabaseSchema } from '../db/adapter';
2
+
3
+ export type DemoGuestbookRow = {
4
+ id: number;
5
+ user_id: string;
6
+ display_name: string;
7
+ message: string;
8
+ created_at: string;
9
+ };
10
+
11
+ export type AppDatabase = {
12
+ mds_demo_guestbook_comments: DemoGuestbookRow;
13
+ } & DatabaseSchema;
@@ -0,0 +1,107 @@
1
+ create table if not exists public.user_onboarding_state (
2
+ user_id uuid primary key references auth.users(id) on delete cascade,
3
+ flow_id text not null default 'mds/onboarding',
4
+ flow_version integer not null default 1,
5
+ status text not null default 'not_started',
6
+ current_step text,
7
+ completed_at timestamptz,
8
+ metadata jsonb not null default '{}'::jsonb,
9
+ created_at timestamptz not null default now(),
10
+ updated_at timestamptz not null default now()
11
+ );
12
+
13
+ alter table public.user_onboarding_state
14
+ add column if not exists flow_id text not null default 'mds/onboarding',
15
+ add column if not exists flow_version integer not null default 1,
16
+ add column if not exists status text not null default 'not_started',
17
+ add column if not exists current_step text,
18
+ add column if not exists completed_at timestamptz,
19
+ add column if not exists metadata jsonb not null default '{}'::jsonb,
20
+ add column if not exists created_at timestamptz not null default now(),
21
+ add column if not exists updated_at timestamptz not null default now();
22
+
23
+ alter table public.user_onboarding_state enable row level security;
24
+
25
+ drop policy if exists "Users can read their onboarding state" on public.user_onboarding_state;
26
+ create policy "Users can read their onboarding state"
27
+ on public.user_onboarding_state
28
+ for select
29
+ to authenticated
30
+ using (auth.uid() = user_id);
31
+
32
+ drop policy if exists "Users can upsert their onboarding state" on public.user_onboarding_state;
33
+ drop policy if exists "Users can insert their onboarding state" on public.user_onboarding_state;
34
+ create policy "Users can insert their onboarding state"
35
+ on public.user_onboarding_state
36
+ for insert
37
+ to authenticated
38
+ with check (auth.uid() = user_id);
39
+
40
+ drop policy if exists "Users can update their onboarding state" on public.user_onboarding_state;
41
+ create policy "Users can update their onboarding state"
42
+ on public.user_onboarding_state
43
+ for update
44
+ to authenticated
45
+ using (auth.uid() = user_id)
46
+ with check (auth.uid() = user_id);
47
+
48
+ create table if not exists public.user_legal_acceptances (
49
+ id uuid primary key default gen_random_uuid(),
50
+ user_id uuid not null references auth.users(id) on delete cascade,
51
+ document_id text not null,
52
+ document_version text not null,
53
+ acceptance_version text,
54
+ flow_id text,
55
+ accepted_at timestamptz not null default now(),
56
+ metadata jsonb not null default '{}'::jsonb,
57
+ unique (user_id, document_id, document_version)
58
+ );
59
+
60
+ alter table public.user_legal_acceptances
61
+ add column if not exists document_id text not null default 'legacy',
62
+ add column if not exists document_version text not null default 'legacy',
63
+ add column if not exists acceptance_version text,
64
+ add column if not exists flow_id text,
65
+ add column if not exists accepted_at timestamptz not null default now(),
66
+ add column if not exists metadata jsonb not null default '{}'::jsonb;
67
+
68
+ do $$
69
+ begin
70
+ if exists (
71
+ select 1
72
+ from information_schema.columns
73
+ where table_schema = 'public'
74
+ and table_name = 'user_legal_acceptances'
75
+ and column_name = 'acceptance_version'
76
+ ) then
77
+ update public.user_legal_acceptances
78
+ set document_version = acceptance_version
79
+ where document_version = 'legacy'
80
+ and acceptance_version is not null;
81
+
82
+ alter table public.user_legal_acceptances
83
+ alter column acceptance_version drop not null;
84
+ end if;
85
+ end $$;
86
+
87
+ create unique index if not exists user_legal_acceptances_user_document_version_idx
88
+ on public.user_legal_acceptances (user_id, document_id, document_version);
89
+
90
+ alter table public.user_legal_acceptances enable row level security;
91
+
92
+ drop policy if exists "Users can read their legal acceptances" on public.user_legal_acceptances;
93
+ create policy "Users can read their legal acceptances"
94
+ on public.user_legal_acceptances
95
+ for select
96
+ to authenticated
97
+ using (auth.uid() = user_id);
98
+
99
+ drop policy if exists "Users can record their legal acceptances" on public.user_legal_acceptances;
100
+ create policy "Users can record their legal acceptances"
101
+ on public.user_legal_acceptances
102
+ for insert
103
+ to authenticated
104
+ with check (auth.uid() = user_id);
105
+
106
+ grant select, insert, update on public.user_onboarding_state to authenticated;
107
+ grant select, insert on public.user_legal_acceptances to authenticated;
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMV,WAAW,EAKZ,MAAM,YAAY,CAAC;AAwnDpB,eAAO,MAAM,cAAc,EAAE,SAAS,WAAW,EAKhD,CAAC"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMV,WAAW,EAKZ,MAAM,YAAY,CAAC;AA8sEpB,eAAO,MAAM,cAAc,EAAE,SAAS,WAAW,EAKhD,CAAC"}