@axonpack/preview 0.0.0-stage → 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.
- package/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +118 -2
- package/android/build.gradle +21 -0
- package/android/consumer-rules.pro +3 -0
- package/android/src/main/java/expo/modules/axonpackpreview/AxonpackPreviewModule.kt +72 -0
- package/android/src/main/java/expo/modules/axonpackpreview/BundleLoaderOverride.kt +41 -0
- package/android/src/main/java/expo/modules/axonpackpreview/HermesHeader.kt +24 -0
- package/android/src/main/java/expo/modules/axonpackpreview/PreviewPackage.kt +76 -0
- package/android/src/main/java/expo/modules/axonpackpreview/PreviewState.kt +295 -0
- package/app.plugin.js +112 -0
- package/bin/preview.js +2 -0
- package/build/cli.cjs +1465 -0
- package/build/cli.d.ts +3 -0
- package/build/cli.d.ts.map +1 -0
- package/build/cli.js +164 -0
- package/build/cli.js.map +1 -0
- package/build/components/preview-list/preview-list.component.d.ts +13 -0
- package/build/components/preview-list/preview-list.component.d.ts.map +1 -0
- package/build/components/preview-list/preview-list.component.js +316 -0
- package/build/components/preview-list/preview-list.component.js.map +1 -0
- package/build/components/preview-list/preview-list.types.d.ts +59 -0
- package/build/components/preview-list/preview-list.types.d.ts.map +1 -0
- package/build/components/preview-list/preview-list.types.js +2 -0
- package/build/components/preview-list/preview-list.types.js.map +1 -0
- package/build/components/preview-provider/preview-provider.component.d.ts +12 -0
- package/build/components/preview-provider/preview-provider.component.d.ts.map +1 -0
- package/build/components/preview-provider/preview-provider.component.js +19 -0
- package/build/components/preview-provider/preview-provider.component.js.map +1 -0
- package/build/constants/dev-preview-servers/dev-preview-servers.const.d.ts +26 -0
- package/build/constants/dev-preview-servers/dev-preview-servers.const.d.ts.map +1 -0
- package/build/constants/dev-preview-servers/dev-preview-servers.const.js +9 -0
- package/build/constants/dev-preview-servers/dev-preview-servers.const.js.map +1 -0
- package/build/constants/preview-list/theme.const.d.ts +5 -0
- package/build/constants/preview-list/theme.const.d.ts.map +1 -0
- package/build/constants/preview-list/theme.const.js +65 -0
- package/build/constants/preview-list/theme.const.js.map +1 -0
- package/build/index.d.ts +24 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +16 -0
- package/build/index.js.map +1 -0
- package/build/services/cli/config.service.d.ts +13 -0
- package/build/services/cli/config.service.d.ts.map +1 -0
- package/build/services/cli/config.service.js +39 -0
- package/build/services/cli/config.service.js.map +1 -0
- package/build/services/cli/project.service.d.ts +25 -0
- package/build/services/cli/project.service.d.ts.map +1 -0
- package/build/services/cli/project.service.js +81 -0
- package/build/services/cli/project.service.js.map +1 -0
- package/build/services/cli/title.service.d.ts +15 -0
- package/build/services/cli/title.service.d.ts.map +1 -0
- package/build/services/cli/title.service.js +24 -0
- package/build/services/cli/title.service.js.map +1 -0
- package/build/services/dev-preview-servers/discover.service.d.ts +14 -0
- package/build/services/dev-preview-servers/discover.service.d.ts.map +1 -0
- package/build/services/dev-preview-servers/discover.service.js +106 -0
- package/build/services/dev-preview-servers/discover.service.js.map +1 -0
- package/build/services/native/build-info.service.d.ts +11 -0
- package/build/services/native/build-info.service.d.ts.map +1 -0
- package/build/services/native/build-info.service.js +18 -0
- package/build/services/native/build-info.service.js.map +1 -0
- package/build/services/native/native.service.d.ts +24 -0
- package/build/services/native/native.service.d.ts.map +1 -0
- package/build/services/native/native.service.js +13 -0
- package/build/services/native/native.service.js.map +1 -0
- package/build/services/previews/download.service.d.ts +14 -0
- package/build/services/previews/download.service.d.ts.map +1 -0
- package/build/services/previews/download.service.js +66 -0
- package/build/services/previews/download.service.js.map +1 -0
- package/build/services/previews/local-previews.service.d.ts +25 -0
- package/build/services/previews/local-previews.service.d.ts.map +1 -0
- package/build/services/previews/local-previews.service.js +50 -0
- package/build/services/previews/local-previews.service.js.map +1 -0
- package/build/services/previews/reload.service.d.ts +6 -0
- package/build/services/previews/reload.service.d.ts.map +1 -0
- package/build/services/previews/reload.service.js +13 -0
- package/build/services/previews/reload.service.js.map +1 -0
- package/build/services/previews/remote.service.d.ts +11 -0
- package/build/services/previews/remote.service.d.ts.map +1 -0
- package/build/services/previews/remote.service.js +34 -0
- package/build/services/previews/remote.service.js.map +1 -0
- package/build/services/previews/select.service.d.ts +11 -0
- package/build/services/previews/select.service.d.ts.map +1 -0
- package/build/services/previews/select.service.js +25 -0
- package/build/services/previews/select.service.js.map +1 -0
- package/build/services/previews/use-preview.service.d.ts +21 -0
- package/build/services/previews/use-preview.service.d.ts.map +1 -0
- package/build/services/previews/use-preview.service.js +24 -0
- package/build/services/previews/use-preview.service.js.map +1 -0
- package/build/services/previews/use-running.service.d.ts +4 -0
- package/build/services/previews/use-running.service.d.ts.map +1 -0
- package/build/services/previews/use-running.service.js +21 -0
- package/build/services/previews/use-running.service.js.map +1 -0
- package/build/services/publish/bundle.service.d.ts +11 -0
- package/build/services/publish/bundle.service.d.ts.map +1 -0
- package/build/services/publish/bundle.service.js +46 -0
- package/build/services/publish/bundle.service.js.map +1 -0
- package/build/services/publish/commands.service.d.ts +23 -0
- package/build/services/publish/commands.service.d.ts.map +1 -0
- package/build/services/publish/commands.service.js +130 -0
- package/build/services/publish/commands.service.js.map +1 -0
- package/build/services/publish/eas-env.service.d.ts +9 -0
- package/build/services/publish/eas-env.service.d.ts.map +1 -0
- package/build/services/publish/eas-env.service.js +49 -0
- package/build/services/publish/eas-env.service.js.map +1 -0
- package/build/services/registry/registry.service.d.ts +27 -0
- package/build/services/registry/registry.service.d.ts.map +1 -0
- package/build/services/registry/registry.service.js +89 -0
- package/build/services/registry/registry.service.js.map +1 -0
- package/build/services/s3/s3.service.d.ts +59 -0
- package/build/services/s3/s3.service.d.ts.map +1 -0
- package/build/services/s3/s3.service.js +154 -0
- package/build/services/s3/s3.service.js.map +1 -0
- package/build/services/start/start.service.d.ts +48 -0
- package/build/services/start/start.service.d.ts.map +1 -0
- package/build/services/start/start.service.js +172 -0
- package/build/services/start/start.service.js.map +1 -0
- package/build/stores/dev-preview-servers/dev-preview-servers.store.d.ts +21 -0
- package/build/stores/dev-preview-servers/dev-preview-servers.store.d.ts.map +1 -0
- package/build/stores/dev-preview-servers/dev-preview-servers.store.js +91 -0
- package/build/stores/dev-preview-servers/dev-preview-servers.store.js.map +1 -0
- package/build/stores/previews/previews.store.d.ts +36 -0
- package/build/stores/previews/previews.store.d.ts.map +1 -0
- package/build/stores/previews/previews.store.js +134 -0
- package/build/stores/previews/previews.store.js.map +1 -0
- package/build/utils/config/config.util.d.ts +39 -0
- package/build/utils/config/config.util.d.ts.map +1 -0
- package/build/utils/config/config.util.js +24 -0
- package/build/utils/config/config.util.js.map +1 -0
- package/build/utils/config/expo-config.util.d.ts +30 -0
- package/build/utils/config/expo-config.util.d.ts.map +1 -0
- package/build/utils/config/expo-config.util.js +43 -0
- package/build/utils/config/expo-config.util.js.map +1 -0
- package/build/utils/dev-preview-servers/merge-servers.util.d.ts +47 -0
- package/build/utils/dev-preview-servers/merge-servers.util.d.ts.map +1 -0
- package/build/utils/dev-preview-servers/merge-servers.util.js +37 -0
- package/build/utils/dev-preview-servers/merge-servers.util.js.map +1 -0
- package/build/utils/preview-list/theme.util.d.ts +5 -0
- package/build/utils/preview-list/theme.util.d.ts.map +1 -0
- package/build/utils/preview-list/theme.util.js +12 -0
- package/build/utils/preview-list/theme.util.js.map +1 -0
- package/build/utils/previews/layout.util.d.ts +89 -0
- package/build/utils/previews/layout.util.d.ts.map +1 -0
- package/build/utils/previews/layout.util.js +30 -0
- package/build/utils/previews/layout.util.js.map +1 -0
- package/build/utils/previews/preview-items.util.d.ts +23 -0
- package/build/utils/previews/preview-items.util.d.ts.map +1 -0
- package/build/utils/previews/preview-items.util.js +39 -0
- package/build/utils/previews/preview-items.util.js.map +1 -0
- package/build/utils/previews/preview-title.util.d.ts +2 -0
- package/build/utils/previews/preview-title.util.d.ts.map +1 -0
- package/build/utils/previews/preview-title.util.js +6 -0
- package/build/utils/previews/preview-title.util.js.map +1 -0
- package/build/utils/previews/running.util.d.ts +23 -0
- package/build/utils/previews/running.util.d.ts.map +1 -0
- package/build/utils/previews/running.util.js +23 -0
- package/build/utils/previews/running.util.js.map +1 -0
- package/build/utils/publish/changelog.util.d.ts +5 -0
- package/build/utils/publish/changelog.util.d.ts.map +1 -0
- package/build/utils/publish/changelog.util.js +19 -0
- package/build/utils/publish/changelog.util.js.map +1 -0
- package/build/utils/publish/indexes.util.d.ts +12 -0
- package/build/utils/publish/indexes.util.d.ts.map +1 -0
- package/build/utils/publish/indexes.util.js +52 -0
- package/build/utils/publish/indexes.util.js.map +1 -0
- package/build/utils/s3/sigv4.util.d.ts +24 -0
- package/build/utils/s3/sigv4.util.d.ts.map +1 -0
- package/build/utils/s3/sigv4.util.js +67 -0
- package/build/utils/s3/sigv4.util.js.map +1 -0
- package/expo-module.config.json +10 -0
- package/ios/AxonpackPreview.podspec +30 -0
- package/ios/AxonpackPreviewModule.swift +55 -0
- package/ios/PreviewReactDelegateHandler.swift +147 -0
- package/ios/PreviewState.swift +236 -0
- package/notes/README.md +36 -0
- package/notes/bundles.md +35 -0
- package/notes/dev-preview-servers.md +67 -0
- package/notes/distribution.md +138 -0
- package/notes/native-loader.md +56 -0
- package/notes/storage.md +145 -0
- package/notes/testing.md +97 -0
- package/package.json +107 -4
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { useSyncExternalStore } from "react";
|
|
2
|
+
import { currentPlatform, resolveBuildKey, } from "../../utils/config/config.util";
|
|
3
|
+
import { downloadPreview } from "../../services/previews/download.service";
|
|
4
|
+
import { deleteLocalPreview, listLocalPreviews, } from "../../services/previews/local-previews.service";
|
|
5
|
+
import { nativeModule, selectedPreviewId, } from "../../services/native/native.service";
|
|
6
|
+
import { previewBundlePath } from "../../services/previews/select.service";
|
|
7
|
+
import { fetchPreviews } from "../../services/previews/remote.service";
|
|
8
|
+
let state = {
|
|
9
|
+
loading: false,
|
|
10
|
+
error: null,
|
|
11
|
+
buildKey: null,
|
|
12
|
+
remote: null,
|
|
13
|
+
local: [],
|
|
14
|
+
downloading: {},
|
|
15
|
+
activeId: null,
|
|
16
|
+
broken: [],
|
|
17
|
+
};
|
|
18
|
+
const listeners = new Set();
|
|
19
|
+
const set = (patch) => {
|
|
20
|
+
state = { ...state, ...patch };
|
|
21
|
+
listeners.forEach((listener) => listener());
|
|
22
|
+
};
|
|
23
|
+
const readLocal = async () => {
|
|
24
|
+
const platform = currentPlatform();
|
|
25
|
+
const nativeState = nativeModule()?.state() ?? {};
|
|
26
|
+
set({
|
|
27
|
+
local: platform ? await listLocalPreviews(platform) : [],
|
|
28
|
+
activeId: selectedPreviewId(nativeState),
|
|
29
|
+
broken: nativeState.broken ?? [],
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
const message = (error) => error instanceof Error ? error.message : String(error);
|
|
33
|
+
export const previewsStore = {
|
|
34
|
+
getState: () => state,
|
|
35
|
+
subscribe(listener) {
|
|
36
|
+
listeners.add(listener);
|
|
37
|
+
return () => listeners.delete(listener);
|
|
38
|
+
},
|
|
39
|
+
/** Reads the downloads on the device, then asks the bucket for this build's list. */
|
|
40
|
+
async refresh(config) {
|
|
41
|
+
set({
|
|
42
|
+
loading: true,
|
|
43
|
+
error: null,
|
|
44
|
+
buildKey: resolveBuildKey(config),
|
|
45
|
+
});
|
|
46
|
+
try {
|
|
47
|
+
await readLocal();
|
|
48
|
+
const index = await fetchPreviews(config);
|
|
49
|
+
set({ remote: index.previews, loading: false });
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
set({ loading: false, error: message(error) });
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
async download(config, id) {
|
|
56
|
+
const entry = state.remote?.find((p) => p.id === id);
|
|
57
|
+
if (!entry || id in state.downloading)
|
|
58
|
+
return;
|
|
59
|
+
set({ downloading: { ...state.downloading, [id]: 0 }, error: null });
|
|
60
|
+
try {
|
|
61
|
+
await downloadPreview(config, entry, ({ bytes, totalBytes }) => set({
|
|
62
|
+
downloading: {
|
|
63
|
+
...state.downloading,
|
|
64
|
+
[id]: totalBytes ? bytes / totalBytes : 0,
|
|
65
|
+
},
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
set({ error: message(error) });
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
const { [id]: _, ...rest } = state.downloading;
|
|
73
|
+
set({ downloading: rest });
|
|
74
|
+
await readLocal();
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
/**
|
|
78
|
+
* Restarts into a preview, downloading it first when it is not on the device, or into the base
|
|
79
|
+
* bundle with null. A preview with an update keeps its downloaded copy until QA updates it.
|
|
80
|
+
*/
|
|
81
|
+
async switchTo(config, id) {
|
|
82
|
+
const native = nativeModule();
|
|
83
|
+
const platform = currentPlatform();
|
|
84
|
+
if (!native || !platform)
|
|
85
|
+
return;
|
|
86
|
+
if (id !== null &&
|
|
87
|
+
!state.local.some((p) => p.id === id && p.key === state.buildKey)) {
|
|
88
|
+
await previewsStore.download(config, id);
|
|
89
|
+
if (!state.local.some((p) => p.id === id))
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const local = state.local.find((p) => p.id === id);
|
|
93
|
+
// A native side older than this JS (an app not rebuilt since the package changed) throws here.
|
|
94
|
+
// The list shows the reason instead of the button silently doing nothing.
|
|
95
|
+
try {
|
|
96
|
+
// "Back to base" also stops a local Metro server, so it always means the default.
|
|
97
|
+
if (id === null && typeof native.selectLocalServer === "function") {
|
|
98
|
+
native.selectLocalServer(null, null);
|
|
99
|
+
}
|
|
100
|
+
native.select(id === null ? null : previewBundlePath(id), local?.key ?? null);
|
|
101
|
+
native.reload();
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
set({ error: message(error) });
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
/** Deletes a download. If it is the one running, the app goes back to the base bundle first. */
|
|
108
|
+
async remove(id) {
|
|
109
|
+
const platform = currentPlatform();
|
|
110
|
+
if (!platform)
|
|
111
|
+
return;
|
|
112
|
+
const native = nativeModule();
|
|
113
|
+
try {
|
|
114
|
+
if (state.activeId === id && native) {
|
|
115
|
+
native.select(null, null);
|
|
116
|
+
native.reload();
|
|
117
|
+
}
|
|
118
|
+
deleteLocalPreview(id, platform);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
set({ error: message(error) });
|
|
122
|
+
}
|
|
123
|
+
await readLocal();
|
|
124
|
+
},
|
|
125
|
+
/** Deletes every download made for another native build. */
|
|
126
|
+
async removeIncompatible() {
|
|
127
|
+
for (const preview of state.local) {
|
|
128
|
+
if (preview.key !== state.buildKey)
|
|
129
|
+
await previewsStore.remove(preview.id);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
export const usePreviewsState = () => useSyncExternalStore(previewsStore.subscribe, previewsStore.getState);
|
|
134
|
+
//# sourceMappingURL=previews.store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"previews.store.js","sourceRoot":"","sources":["../../../src/stores/previews/previews.store.ts"],"names":[],"mappings":"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","sourcesContent":["import { useSyncExternalStore } from \"react\";\n\nimport {\n PreviewConfig,\n currentPlatform,\n resolveBuildKey,\n} from \"../../utils/config/config.util\";\nimport type { IndexEntry } from \"../../utils/previews/layout.util\";\nimport { downloadPreview } from \"../../services/previews/download.service\";\nimport {\n LocalPreview,\n deleteLocalPreview,\n listLocalPreviews,\n} from \"../../services/previews/local-previews.service\";\nimport {\n nativeModule,\n selectedPreviewId,\n} from \"../../services/native/native.service\";\nimport { previewBundlePath } from \"../../services/previews/select.service\";\nimport { fetchPreviews } from \"../../services/previews/remote.service\";\n\nexport type PreviewsState = {\n loading: boolean;\n error: string | null;\n /** This build's key; downloads made for any other are incompatible. */\n buildKey: string | null;\n /** What the bucket lists for this build. Null until it has answered once. */\n remote: IndexEntry[] | null;\n local: LocalPreview[];\n /** Download progress by id, from 0 to 1. */\n downloading: Record<string, number>;\n /** The preview the next start loads, or null for the base bundle. */\n activeId: string | null;\n /** Previews that stopped before they finished starting, so the base bundle loaded instead. */\n broken: string[];\n};\n\nlet state: PreviewsState = {\n loading: false,\n error: null,\n buildKey: null,\n remote: null,\n local: [],\n downloading: {},\n activeId: null,\n broken: [],\n};\nconst listeners = new Set<() => void>();\n\nconst set = (patch: Partial<PreviewsState>) => {\n state = { ...state, ...patch };\n listeners.forEach((listener) => listener());\n};\n\nconst readLocal = async () => {\n const platform = currentPlatform();\n const nativeState = nativeModule()?.state() ?? {};\n set({\n local: platform ? await listLocalPreviews(platform) : [],\n activeId: selectedPreviewId(nativeState),\n broken: nativeState.broken ?? [],\n });\n};\n\nconst message = (error: unknown) =>\n error instanceof Error ? error.message : String(error);\n\nexport const previewsStore = {\n getState: () => state,\n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n\n /** Reads the downloads on the device, then asks the bucket for this build's list. */\n async refresh(config: PreviewConfig) {\n set({\n loading: true,\n error: null,\n buildKey: resolveBuildKey(config),\n });\n try {\n await readLocal();\n const index = await fetchPreviews(config);\n set({ remote: index.previews, loading: false });\n } catch (error) {\n set({ loading: false, error: message(error) });\n }\n },\n\n async download(config: PreviewConfig, id: string) {\n const entry = state.remote?.find((p) => p.id === id);\n if (!entry || id in state.downloading) return;\n set({ downloading: { ...state.downloading, [id]: 0 }, error: null });\n try {\n await downloadPreview(config, entry, ({ bytes, totalBytes }) =>\n set({\n downloading: {\n ...state.downloading,\n [id]: totalBytes ? bytes / totalBytes : 0,\n },\n }),\n );\n } catch (error) {\n set({ error: message(error) });\n } finally {\n const { [id]: _, ...rest } = state.downloading;\n set({ downloading: rest });\n await readLocal();\n }\n },\n\n /**\n * Restarts into a preview, downloading it first when it is not on the device, or into the base\n * bundle with null. A preview with an update keeps its downloaded copy until QA updates it.\n */\n async switchTo(config: PreviewConfig, id: string | null) {\n const native = nativeModule();\n const platform = currentPlatform();\n if (!native || !platform) return;\n if (\n id !== null &&\n !state.local.some((p) => p.id === id && p.key === state.buildKey)\n ) {\n await previewsStore.download(config, id);\n if (!state.local.some((p) => p.id === id)) return;\n }\n const local = state.local.find((p) => p.id === id);\n // A native side older than this JS (an app not rebuilt since the package changed) throws here.\n // The list shows the reason instead of the button silently doing nothing.\n try {\n // \"Back to base\" also stops a local Metro server, so it always means the default.\n if (id === null && typeof native.selectLocalServer === \"function\") {\n native.selectLocalServer(null, null);\n }\n native.select(\n id === null ? null : previewBundlePath(id),\n local?.key ?? null,\n );\n native.reload();\n } catch (error) {\n set({ error: message(error) });\n }\n },\n\n /** Deletes a download. If it is the one running, the app goes back to the base bundle first. */\n async remove(id: string) {\n const platform = currentPlatform();\n if (!platform) return;\n const native = nativeModule();\n try {\n if (state.activeId === id && native) {\n native.select(null, null);\n native.reload();\n }\n deleteLocalPreview(id, platform);\n } catch (error) {\n set({ error: message(error) });\n }\n await readLocal();\n },\n\n /** Deletes every download made for another native build. */\n async removeIncompatible() {\n for (const preview of state.local) {\n if (preview.key !== state.buildKey)\n await previewsStore.remove(preview.id);\n }\n },\n};\n\nexport const usePreviewsState = () =>\n useSyncExternalStore(previewsStore.subscribe, previewsStore.getState);\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Platform } from "../previews/layout.util";
|
|
2
|
+
import { S3Config } from "../../services/s3/s3.service";
|
|
3
|
+
/**
|
|
4
|
+
* What the app passes in. It mirrors the publish side's `.env`: the same bucket URL, plus a
|
|
5
|
+
* read-only key when the bucket is private. Nothing here is read from the environment; the app
|
|
6
|
+
* decides where each value comes from.
|
|
7
|
+
*/
|
|
8
|
+
export type PreviewConfig = {
|
|
9
|
+
/** Previews are on only when this is true. The app decides per build; nothing is detected. */
|
|
10
|
+
enabled: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Where the previews are. With a read key: `<endpoint>/<bucket>[/<folder>]`, the same value as
|
|
13
|
+
* `PREVIEW_S3_URL` when publishing. Without one, any address the objects are public under:
|
|
14
|
+
* that same URL for a public bucket, or R2's `https://pub-<id>.r2.dev` or a CDN.
|
|
15
|
+
*/
|
|
16
|
+
url: string;
|
|
17
|
+
/** Read-only key, for a private bucket. Leave out for a public one. Never the write key. */
|
|
18
|
+
readAccessKeyId?: string;
|
|
19
|
+
readSecretAccessKey?: string;
|
|
20
|
+
/** Signing region. Default us-east-1, which MinIO and R2 accept. */
|
|
21
|
+
region?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Lists the Metro servers for this app running on the developer's computer, and switches
|
|
24
|
+
* between them live. Debug builds only; off unless `enabled` is true.
|
|
25
|
+
*/
|
|
26
|
+
devPreviewServers?: boolean;
|
|
27
|
+
/** Extra headers on every read, for a proxy, CDN or tunnel in front of the bucket. */
|
|
28
|
+
headers?: Record<string, string>;
|
|
29
|
+
/**
|
|
30
|
+
* This build's key (`version-<app version>` or `fingerprint-<hash>`), only when the config plugin
|
|
31
|
+
* is not used to bake it in.
|
|
32
|
+
*/
|
|
33
|
+
buildKey?: string;
|
|
34
|
+
};
|
|
35
|
+
export declare function toS3Config(config: PreviewConfig): S3Config;
|
|
36
|
+
export declare const currentPlatform: () => Platform | null;
|
|
37
|
+
/** The build to ask previews for. Null means previews cannot be listed on this build. */
|
|
38
|
+
export declare const resolveBuildKey: (config: PreviewConfig) => string | null;
|
|
39
|
+
//# sourceMappingURL=config.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.util.d.ts","sourceRoot":"","sources":["../../../src/utils/config/config.util.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAEL,QAAQ,EAET,MAAM,8BAA8B,CAAC;AAEtC;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,8FAA8F;IAC9F,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,4FAA4F;IAC5F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,QAAQ,CAgB1D;AAED,eAAO,MAAM,eAAe,QAAO,QAAQ,GAAG,IACiC,CAAC;AAEhF,yFAAyF;AACzF,eAAO,MAAM,eAAe,GAAI,QAAQ,aAAa,KAAG,MAAM,GAAG,IAClC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Platform as RNPlatform } from "react-native";
|
|
2
|
+
import { buildKey } from "../../services/native/build-info.service";
|
|
3
|
+
import { DEFAULT_REGION, parseBucketUrl, } from "../../services/s3/s3.service";
|
|
4
|
+
export function toS3Config(config) {
|
|
5
|
+
const region = config.region ?? DEFAULT_REGION;
|
|
6
|
+
const { headers } = config;
|
|
7
|
+
// Signing needs the bucket apart from the endpoint; a plain read only needs the base address.
|
|
8
|
+
if (config.readAccessKeyId && config.readSecretAccessKey) {
|
|
9
|
+
return {
|
|
10
|
+
...parseBucketUrl(config.url),
|
|
11
|
+
region,
|
|
12
|
+
credentials: {
|
|
13
|
+
accessKeyId: config.readAccessKeyId,
|
|
14
|
+
secretAccessKey: config.readSecretAccessKey,
|
|
15
|
+
},
|
|
16
|
+
headers,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return { endpoint: config.url.trim(), region, headers };
|
|
20
|
+
}
|
|
21
|
+
export const currentPlatform = () => RNPlatform.OS === "android" || RNPlatform.OS === "ios" ? RNPlatform.OS : null;
|
|
22
|
+
/** The build to ask previews for. Null means previews cannot be listed on this build. */
|
|
23
|
+
export const resolveBuildKey = (config) => config.buildKey ?? buildKey();
|
|
24
|
+
//# sourceMappingURL=config.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.util.js","sourceRoot":"","sources":["../../../src/utils/config/config.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AAEpE,OAAO,EACL,cAAc,EAEd,cAAc,GACf,MAAM,8BAA8B,CAAC;AAmCtC,MAAM,UAAU,UAAU,CAAC,MAAqB;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,cAAc,CAAC;IAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAC3B,8FAA8F;IAC9F,IAAI,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;QACzD,OAAO;YACL,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC;YAC7B,MAAM;YACN,WAAW,EAAE;gBACX,WAAW,EAAE,MAAM,CAAC,eAAe;gBACnC,eAAe,EAAE,MAAM,CAAC,mBAAmB;aAC5C;YACD,OAAO;SACR,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,GAAoB,EAAE,CACnD,UAAU,CAAC,EAAE,KAAK,SAAS,IAAI,UAAU,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAEhF,yFAAyF;AACzF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAqB,EAAiB,EAAE,CACtE,MAAM,CAAC,QAAQ,IAAI,QAAQ,EAAE,CAAC","sourcesContent":["import { Platform as RNPlatform } from \"react-native\";\n\nimport { buildKey } from \"../../services/native/build-info.service\";\nimport type { Platform } from \"../previews/layout.util\";\nimport {\n DEFAULT_REGION,\n S3Config,\n parseBucketUrl,\n} from \"../../services/s3/s3.service\";\n\n/**\n * What the app passes in. It mirrors the publish side's `.env`: the same bucket URL, plus a\n * read-only key when the bucket is private. Nothing here is read from the environment; the app\n * decides where each value comes from.\n */\nexport type PreviewConfig = {\n /** Previews are on only when this is true. The app decides per build; nothing is detected. */\n enabled: boolean;\n /**\n * Where the previews are. With a read key: `<endpoint>/<bucket>[/<folder>]`, the same value as\n * `PREVIEW_S3_URL` when publishing. Without one, any address the objects are public under:\n * that same URL for a public bucket, or R2's `https://pub-<id>.r2.dev` or a CDN.\n */\n url: string;\n /** Read-only key, for a private bucket. Leave out for a public one. Never the write key. */\n readAccessKeyId?: string;\n readSecretAccessKey?: string;\n /** Signing region. Default us-east-1, which MinIO and R2 accept. */\n region?: string;\n /**\n * Lists the Metro servers for this app running on the developer's computer, and switches\n * between them live. Debug builds only; off unless `enabled` is true.\n */\n devPreviewServers?: boolean;\n /** Extra headers on every read, for a proxy, CDN or tunnel in front of the bucket. */\n headers?: Record<string, string>;\n /**\n * This build's key (`version-<app version>` or `fingerprint-<hash>`), only when the config plugin\n * is not used to bake it in.\n */\n buildKey?: string;\n};\n\nexport function toS3Config(config: PreviewConfig): S3Config {\n const region = config.region ?? DEFAULT_REGION;\n const { headers } = config;\n // Signing needs the bucket apart from the endpoint; a plain read only needs the base address.\n if (config.readAccessKeyId && config.readSecretAccessKey) {\n return {\n ...parseBucketUrl(config.url),\n region,\n credentials: {\n accessKeyId: config.readAccessKeyId,\n secretAccessKey: config.readSecretAccessKey,\n },\n headers,\n };\n }\n return { endpoint: config.url.trim(), region, headers };\n}\n\nexport const currentPlatform = (): Platform | null =>\n RNPlatform.OS === \"android\" || RNPlatform.OS === \"ios\" ? RNPlatform.OS : null;\n\n/** The build to ask previews for. Null means previews cannot be listed on this build. */\nexport const resolveBuildKey = (config: PreviewConfig): string | null =>\n config.buildKey ?? buildKey();\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Compatibility, Platform } from "../previews/layout.util";
|
|
2
|
+
/** The parts of an Expo app config this package reads. */
|
|
3
|
+
export type AppConfig = {
|
|
4
|
+
version?: string;
|
|
5
|
+
plugins?: (string | [string, unknown?])[];
|
|
6
|
+
ios?: {
|
|
7
|
+
version?: string;
|
|
8
|
+
buildNumber?: string;
|
|
9
|
+
};
|
|
10
|
+
android?: {
|
|
11
|
+
version?: string;
|
|
12
|
+
versionCode?: number;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export declare const PLUGIN_NAME = "@axonpack/preview";
|
|
16
|
+
/** The `compatibility` option of the plugin entry in the app config, or the default. */
|
|
17
|
+
export declare function compatibilityOf(config: AppConfig): Compatibility;
|
|
18
|
+
/** The app version a platform's build reports: its own `version` when set, else `expo.version`. */
|
|
19
|
+
export declare const appVersionOf: (config: AppConfig, platform: Platform) => string;
|
|
20
|
+
export declare const buildNumberOf: (config: AppConfig, platform: Platform) => string;
|
|
21
|
+
/**
|
|
22
|
+
* The setting to publish with: the app config's, unless `--compatibility` overrides it. The
|
|
23
|
+
* warnings say when the two disagree (the build would not see the previews) and what appVersion
|
|
24
|
+
* mode cannot catch.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveCompatibility(fromApp: Compatibility, flag: string | undefined): {
|
|
27
|
+
compatibility: Compatibility;
|
|
28
|
+
warnings: string[];
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=expo-config.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expo-config.util.d.ts","sourceRoot":"","sources":["../../../src/utils/config/expo-config.util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAEb,QAAQ,EAET,MAAM,yBAAyB,CAAC;AAEjC,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,GAAG,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD,CAAC;AAEF,eAAO,MAAM,WAAW,sBAAsB,CAAC;AAE/C,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,CAehE;AAED,mGAAmG;AACnG,eAAO,MAAM,YAAY,GAAI,QAAQ,SAAS,EAAE,UAAU,QAAQ,KAAG,MACV,CAAC;AAE5D,eAAO,MAAM,aAAa,GAAI,QAAQ,SAAS,EAAE,UAAU,QAAQ,KAAG,MAKnE,CAAC;AAEJ;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB;IAAE,aAAa,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAmBtD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { DEFAULT_COMPATIBILITY, isCompatibility, } from "../previews/layout.util";
|
|
2
|
+
export const PLUGIN_NAME = "@axonpack/preview";
|
|
3
|
+
/** The `compatibility` option of the plugin entry in the app config, or the default. */
|
|
4
|
+
export function compatibilityOf(config) {
|
|
5
|
+
for (const plugin of config.plugins ?? []) {
|
|
6
|
+
if (Array.isArray(plugin) && plugin[0] === PLUGIN_NAME) {
|
|
7
|
+
const option = plugin[1]
|
|
8
|
+
?.compatibility;
|
|
9
|
+
if (option === undefined)
|
|
10
|
+
break;
|
|
11
|
+
if (!isCompatibility(option)) {
|
|
12
|
+
throw new Error(`${PLUGIN_NAME}: compatibility must be "appVersion" or "fingerprint"`);
|
|
13
|
+
}
|
|
14
|
+
return option;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return DEFAULT_COMPATIBILITY;
|
|
18
|
+
}
|
|
19
|
+
/** The app version a platform's build reports: its own `version` when set, else `expo.version`. */
|
|
20
|
+
export const appVersionOf = (config, platform) => String(config[platform]?.version ?? config.version ?? "");
|
|
21
|
+
export const buildNumberOf = (config, platform) => String((platform === "ios"
|
|
22
|
+
? config.ios?.buildNumber
|
|
23
|
+
: config.android?.versionCode) ?? "");
|
|
24
|
+
/**
|
|
25
|
+
* The setting to publish with: the app config's, unless `--compatibility` overrides it. The
|
|
26
|
+
* warnings say when the two disagree (the build would not see the previews) and what appVersion
|
|
27
|
+
* mode cannot catch.
|
|
28
|
+
*/
|
|
29
|
+
export function resolveCompatibility(fromApp, flag) {
|
|
30
|
+
if (flag !== undefined && !isCompatibility(flag)) {
|
|
31
|
+
throw new Error(`--compatibility must be appVersion or fingerprint, not ${flag}`);
|
|
32
|
+
}
|
|
33
|
+
const compatibility = flag ?? fromApp;
|
|
34
|
+
const warnings = [];
|
|
35
|
+
if (compatibility !== fromApp) {
|
|
36
|
+
warnings.push(`--compatibility ${compatibility} differs from the app config (${fromApp}), so a build of this app will not list this preview.`);
|
|
37
|
+
}
|
|
38
|
+
if (compatibility === "appVersion") {
|
|
39
|
+
warnings.push("Matched by app version: a native change without a version bump is not detected. Bump the version after native changes, or use fingerprint.");
|
|
40
|
+
}
|
|
41
|
+
return { compatibility, warnings };
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=expo-config.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expo-config.util.js","sourceRoot":"","sources":["../../../src/utils/config/expo-config.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,qBAAqB,EAErB,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAUjC,MAAM,CAAC,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAE/C,wFAAwF;AACxF,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;YACvD,MAAM,MAAM,GAAI,MAAM,CAAC,CAAC,CAA6C;gBACnE,EAAE,aAAa,CAAC;YAClB,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM;YAChC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CACb,GAAG,WAAW,uDAAuD,CACtE,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,mGAAmG;AACnG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAiB,EAAE,QAAkB,EAAU,EAAE,CAC5E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAiB,EAAE,QAAkB,EAAU,EAAE,CAC7E,MAAM,CACJ,CAAC,QAAQ,KAAK,KAAK;IACjB,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,WAAW;IACzB,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,EAAE,CACvC,CAAC;AAEJ;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAsB,EACtB,IAAwB;IAExB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CACb,0DAA0D,IAAI,EAAE,CACjE,CAAC;IACJ,CAAC;IACD,MAAM,aAAa,GAAG,IAAI,IAAI,OAAO,CAAC;IACtC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,aAAa,KAAK,OAAO,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CACX,mBAAmB,aAAa,iCAAiC,OAAO,uDAAuD,CAChI,CAAC;IACJ,CAAC;IACD,IAAI,aAAa,KAAK,YAAY,EAAE,CAAC;QACnC,QAAQ,CAAC,IAAI,CACX,4IAA4I,CAC7I,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;AACrC,CAAC","sourcesContent":["import {\n Compatibility,\n DEFAULT_COMPATIBILITY,\n Platform,\n isCompatibility,\n} from \"../previews/layout.util\";\n\n/** The parts of an Expo app config this package reads. */\nexport type AppConfig = {\n version?: string;\n plugins?: (string | [string, unknown?])[];\n ios?: { version?: string; buildNumber?: string };\n android?: { version?: string; versionCode?: number };\n};\n\nexport const PLUGIN_NAME = \"@axonpack/preview\";\n\n/** The `compatibility` option of the plugin entry in the app config, or the default. */\nexport function compatibilityOf(config: AppConfig): Compatibility {\n for (const plugin of config.plugins ?? []) {\n if (Array.isArray(plugin) && plugin[0] === PLUGIN_NAME) {\n const option = (plugin[1] as { compatibility?: unknown } | undefined)\n ?.compatibility;\n if (option === undefined) break;\n if (!isCompatibility(option)) {\n throw new Error(\n `${PLUGIN_NAME}: compatibility must be \"appVersion\" or \"fingerprint\"`,\n );\n }\n return option;\n }\n }\n return DEFAULT_COMPATIBILITY;\n}\n\n/** The app version a platform's build reports: its own `version` when set, else `expo.version`. */\nexport const appVersionOf = (config: AppConfig, platform: Platform): string =>\n String(config[platform]?.version ?? config.version ?? \"\");\n\nexport const buildNumberOf = (config: AppConfig, platform: Platform): string =>\n String(\n (platform === \"ios\"\n ? config.ios?.buildNumber\n : config.android?.versionCode) ?? \"\",\n );\n\n/**\n * The setting to publish with: the app config's, unless `--compatibility` overrides it. The\n * warnings say when the two disagree (the build would not see the previews) and what appVersion\n * mode cannot catch.\n */\nexport function resolveCompatibility(\n fromApp: Compatibility,\n flag: string | undefined,\n): { compatibility: Compatibility; warnings: string[] } {\n if (flag !== undefined && !isCompatibility(flag)) {\n throw new Error(\n `--compatibility must be appVersion or fingerprint, not ${flag}`,\n );\n }\n const compatibility = flag ?? fromApp;\n const warnings: string[] = [];\n if (compatibility !== fromApp) {\n warnings.push(\n `--compatibility ${compatibility} differs from the app config (${fromApp}), so a build of this app will not list this preview.`,\n );\n }\n if (compatibility === \"appVersion\") {\n warnings.push(\n \"Matched by app version: a native change without a version bump is not detected. Bump the version after native changes, or use fingerprint.\",\n );\n }\n return { compatibility, warnings };\n}\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type AppConfig } from "../config/expo-config.util";
|
|
2
|
+
import { type Platform } from "../previews/layout.util";
|
|
3
|
+
import type { RegisteredServer } from "../../constants/dev-preview-servers/dev-preview-servers.const";
|
|
4
|
+
/** A Metro server on the developer's computer that this app can run from (debug builds only). */
|
|
5
|
+
export type DevPreviewServer = {
|
|
6
|
+
/** `host:port`, also what Android's dev support connects to. */
|
|
7
|
+
hostPort: string;
|
|
8
|
+
host: string;
|
|
9
|
+
port: number;
|
|
10
|
+
/** The bundle URL the server's manifest gives for this platform; what iOS loads. */
|
|
11
|
+
url: string;
|
|
12
|
+
title: string;
|
|
13
|
+
name: string;
|
|
14
|
+
slug: string;
|
|
15
|
+
version: string | null;
|
|
16
|
+
branch: string | null;
|
|
17
|
+
worktree: string | null;
|
|
18
|
+
/** The native build key the server's code is for; null when it cannot be told. */
|
|
19
|
+
key: string | null;
|
|
20
|
+
/** Whether `key` matches the installed build: true, false, or null for "unknown". */
|
|
21
|
+
compatible: boolean | null;
|
|
22
|
+
/** Announced by `preview start` (with branch and worktree), or only found by the scan. */
|
|
23
|
+
announced: boolean;
|
|
24
|
+
};
|
|
25
|
+
export type ScannedServer = {
|
|
26
|
+
host: string;
|
|
27
|
+
port: number;
|
|
28
|
+
url: string;
|
|
29
|
+
expo: AppConfig & {
|
|
30
|
+
slug?: string;
|
|
31
|
+
name?: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Turns what the registry announced and what the scan found into this app's list: other apps'
|
|
36
|
+
* servers (another slug) are left out, the same app with another native key is kept but marked
|
|
37
|
+
* incompatible, and a server found both ways uses the registry's details.
|
|
38
|
+
*/
|
|
39
|
+
export declare function mergeServers(input: {
|
|
40
|
+
registry: RegisteredServer[];
|
|
41
|
+
scanned: ScannedServer[];
|
|
42
|
+
/** The slug the config plugin baked into the build. Only its servers are listed. */
|
|
43
|
+
appSlug: string;
|
|
44
|
+
buildKey: string | null;
|
|
45
|
+
platform: Platform;
|
|
46
|
+
}): DevPreviewServer[];
|
|
47
|
+
//# sourceMappingURL=merge-servers.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-servers.util.d.ts","sourceRoot":"","sources":["../../../src/utils/dev-preview-servers/merge-servers.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+DAA+D,CAAC;AAEtG,iGAAiG;AACjG,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,kFAAkF;IAClF,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,qFAAqF;IACrF,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,0FAA0F;IAC1F,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC;CACpB,GAAG,gBAAgB,EAAE,CA+BrB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { appVersionOf, compatibilityOf, } from "../config/expo-config.util";
|
|
2
|
+
import { compatibilityKey } from "../previews/layout.util";
|
|
3
|
+
/**
|
|
4
|
+
* Turns what the registry announced and what the scan found into this app's list: other apps'
|
|
5
|
+
* servers (another slug) are left out, the same app with another native key is kept but marked
|
|
6
|
+
* incompatible, and a server found both ways uses the registry's details.
|
|
7
|
+
*/
|
|
8
|
+
export function mergeServers(input) {
|
|
9
|
+
const servers = [];
|
|
10
|
+
for (const found of input.scanned) {
|
|
11
|
+
const announced = input.registry.find((r) => r.port === found.port);
|
|
12
|
+
const slug = announced?.slug ?? found.expo.slug ?? "";
|
|
13
|
+
if (slug !== input.appSlug)
|
|
14
|
+
continue;
|
|
15
|
+
const key = announced?.keys[input.platform] ??
|
|
16
|
+
(compatibilityOf(found.expo) === "appVersion"
|
|
17
|
+
? compatibilityKey("appVersion", appVersionOf(found.expo, input.platform))
|
|
18
|
+
: null);
|
|
19
|
+
servers.push({
|
|
20
|
+
hostPort: `${found.host}:${found.port}`,
|
|
21
|
+
host: found.host,
|
|
22
|
+
port: found.port,
|
|
23
|
+
url: found.url,
|
|
24
|
+
title: announced?.title || found.expo.name || slug,
|
|
25
|
+
name: announced?.name ?? found.expo.name ?? "",
|
|
26
|
+
slug,
|
|
27
|
+
version: appVersionOf(found.expo, input.platform) || null,
|
|
28
|
+
branch: announced?.branch || null,
|
|
29
|
+
worktree: announced?.worktree || null,
|
|
30
|
+
key,
|
|
31
|
+
compatible: key && input.buildKey ? key === input.buildKey : null,
|
|
32
|
+
announced: Boolean(announced),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return servers.sort((a, b) => a.port - b.port);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=merge-servers.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-servers.util.js","sourceRoot":"","sources":["../../../src/utils/dev-preview-servers/merge-servers.util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,eAAe,GAEhB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAiB,MAAM,yBAAyB,CAAC;AAgC1E;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAO5B;IACC,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,SAAS,EAAE,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QACtD,IAAI,IAAI,KAAK,KAAK,CAAC,OAAO;YAAE,SAAS;QACrC,MAAM,GAAG,GACP,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC/B,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,YAAY;gBAC3C,CAAC,CAAC,gBAAgB,CACd,YAAY,EACZ,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CACzC;gBACH,CAAC,CAAC,IAAI,CAAC,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC;YACX,QAAQ,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE;YACvC,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI;YAClD,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE;YAC9C,IAAI;YACJ,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI;YACzD,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI,IAAI;YACjC,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI,IAAI;YACrC,GAAG;YACH,UAAU,EAAE,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YACjE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACjD,CAAC","sourcesContent":["import {\n appVersionOf,\n compatibilityOf,\n type AppConfig,\n} from \"../config/expo-config.util\";\nimport { compatibilityKey, type Platform } from \"../previews/layout.util\";\nimport type { RegisteredServer } from \"../../constants/dev-preview-servers/dev-preview-servers.const\";\n\n/** A Metro server on the developer's computer that this app can run from (debug builds only). */\nexport type DevPreviewServer = {\n /** `host:port`, also what Android's dev support connects to. */\n hostPort: string;\n host: string;\n port: number;\n /** The bundle URL the server's manifest gives for this platform; what iOS loads. */\n url: string;\n title: string;\n name: string;\n slug: string;\n version: string | null;\n branch: string | null;\n worktree: string | null;\n /** The native build key the server's code is for; null when it cannot be told. */\n key: string | null;\n /** Whether `key` matches the installed build: true, false, or null for \"unknown\". */\n compatible: boolean | null;\n /** Announced by `preview start` (with branch and worktree), or only found by the scan. */\n announced: boolean;\n};\n\nexport type ScannedServer = {\n host: string;\n port: number;\n url: string;\n expo: AppConfig & { slug?: string; name?: string };\n};\n\n/**\n * Turns what the registry announced and what the scan found into this app's list: other apps'\n * servers (another slug) are left out, the same app with another native key is kept but marked\n * incompatible, and a server found both ways uses the registry's details.\n */\nexport function mergeServers(input: {\n registry: RegisteredServer[];\n scanned: ScannedServer[];\n /** The slug the config plugin baked into the build. Only its servers are listed. */\n appSlug: string;\n buildKey: string | null;\n platform: Platform;\n}): DevPreviewServer[] {\n const servers: DevPreviewServer[] = [];\n for (const found of input.scanned) {\n const announced = input.registry.find((r) => r.port === found.port);\n const slug = announced?.slug ?? found.expo.slug ?? \"\";\n if (slug !== input.appSlug) continue;\n const key =\n announced?.keys[input.platform] ??\n (compatibilityOf(found.expo) === \"appVersion\"\n ? compatibilityKey(\n \"appVersion\",\n appVersionOf(found.expo, input.platform),\n )\n : null);\n servers.push({\n hostPort: `${found.host}:${found.port}`,\n host: found.host,\n port: found.port,\n url: found.url,\n title: announced?.title || found.expo.name || slug,\n name: announced?.name ?? found.expo.name ?? \"\",\n slug,\n version: appVersionOf(found.expo, input.platform) || null,\n branch: announced?.branch || null,\n worktree: announced?.worktree || null,\n key,\n compatible: key && input.buildKey ? key === input.buildKey : null,\n announced: Boolean(announced),\n });\n }\n return servers.sort((a, b) => a.port - b.port);\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PreviewListTheme } from "../../components/preview-list/preview-list.types";
|
|
2
|
+
/** Merges a partial theme over the light or dark base. */
|
|
3
|
+
export declare const resolveTheme: (partial: Partial<PreviewListTheme> | undefined, systemScheme: string | null | undefined) => PreviewListTheme;
|
|
4
|
+
export declare const formatSize: (bytes: number) => string;
|
|
5
|
+
//# sourceMappingURL=theme.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.util.d.ts","sourceRoot":"","sources":["../../../src/utils/preview-list/theme.util.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAC;AAEzF,0DAA0D;AAC1D,eAAO,MAAM,YAAY,GACvB,SAAS,OAAO,CAAC,gBAAgB,CAAC,GAAG,SAAS,EAC9C,cAAc,MAAM,GAAG,IAAI,GAAG,SAAS,KACtC,gBAKF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAGQ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DARK_THEME, LIGHT_THEME, } from "../../constants/preview-list/theme.const";
|
|
2
|
+
/** Merges a partial theme over the light or dark base. */
|
|
3
|
+
export const resolveTheme = (partial, systemScheme) => {
|
|
4
|
+
const mode = partial?.mode ?? "auto";
|
|
5
|
+
const dark = mode === "dark" || (mode === "auto" && systemScheme === "dark");
|
|
6
|
+
const base = dark ? DARK_THEME : LIGHT_THEME;
|
|
7
|
+
return { ...base, ...partial, fonts: { ...base.fonts, ...partial?.fonts } };
|
|
8
|
+
};
|
|
9
|
+
export const formatSize = (bytes) => bytes >= 1024 * 1024
|
|
10
|
+
? `${(bytes / 1024 / 1024).toFixed(1)} MB`
|
|
11
|
+
: `${Math.max(1, Math.round(bytes / 1024))} KB`;
|
|
12
|
+
//# sourceMappingURL=theme.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.util.js","sourceRoot":"","sources":["../../../src/utils/preview-list/theme.util.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,GACZ,MAAM,0CAA0C,CAAC;AAGlD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAA8C,EAC9C,YAAuC,EACrB,EAAE;IACpB,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,MAAM,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,YAAY,KAAK,MAAM,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;IAC7C,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;AAC9E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAU,EAAE,CAClD,KAAK,IAAI,IAAI,GAAG,IAAI;IAClB,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;IAC1C,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC","sourcesContent":["import {\n DARK_THEME,\n LIGHT_THEME,\n} from \"../../constants/preview-list/theme.const\";\nimport type { PreviewListTheme } from \"../../components/preview-list/preview-list.types\";\n\n/** Merges a partial theme over the light or dark base. */\nexport const resolveTheme = (\n partial: Partial<PreviewListTheme> | undefined,\n systemScheme: string | null | undefined,\n): PreviewListTheme => {\n const mode = partial?.mode ?? \"auto\";\n const dark = mode === \"dark\" || (mode === \"auto\" && systemScheme === \"dark\");\n const base = dark ? DARK_THEME : LIGHT_THEME;\n return { ...base, ...partial, fonts: { ...base.fonts, ...partial?.fonts } };\n};\n\nexport const formatSize = (bytes: number): string =>\n bytes >= 1024 * 1024\n ? `${(bytes / 1024 / 1024).toFixed(1)} MB`\n : `${Math.max(1, Math.round(bytes / 1024))} KB`;\n"]}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export declare const SCHEMA = 1;
|
|
2
|
+
export type Platform = "android" | "ios";
|
|
3
|
+
export declare const PLATFORMS: Platform[];
|
|
4
|
+
/**
|
|
5
|
+
* How a preview is matched to a native build. `appVersion` (the default) trusts the app's version:
|
|
6
|
+
* simple, but a native change without a version bump goes unnoticed. `fingerprint` hashes the
|
|
7
|
+
* native side, so any native change makes older previews incompatible.
|
|
8
|
+
*/
|
|
9
|
+
export type Compatibility = "appVersion" | "fingerprint";
|
|
10
|
+
export declare const DEFAULT_COMPATIBILITY: Compatibility;
|
|
11
|
+
export declare const isCompatibility: (value: unknown) => value is Compatibility;
|
|
12
|
+
/**
|
|
13
|
+
* The key a build and its previews share. Characters a bucket path should not carry are replaced,
|
|
14
|
+
* so any version string works. app.plugin.js builds the same key; a test keeps the two in step.
|
|
15
|
+
*/
|
|
16
|
+
export declare const compatibilityKey: (compatibility: Compatibility, value: string) => string;
|
|
17
|
+
/** The setting a key was made with, read back from its prefix. */
|
|
18
|
+
export declare const compatibilityOfKey: (key: string) => Compatibility;
|
|
19
|
+
/** What `expo export:embed` names the bundle, so a preview folder matches what a build embeds. */
|
|
20
|
+
export declare const BUNDLE_FILE: Record<Platform, string>;
|
|
21
|
+
export type ManifestFile = {
|
|
22
|
+
path: string;
|
|
23
|
+
sha256: string;
|
|
24
|
+
size: number;
|
|
25
|
+
};
|
|
26
|
+
/** Shown to QA in the list, and kept in both the manifest and the index entry. */
|
|
27
|
+
export type PreviewInfo = {
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
branch: string;
|
|
31
|
+
commit: string;
|
|
32
|
+
author: string;
|
|
33
|
+
publishedAt: string;
|
|
34
|
+
appVersion: string;
|
|
35
|
+
buildNumber: string;
|
|
36
|
+
compatibility: Compatibility;
|
|
37
|
+
/** The native build's fingerprint when it was published, whatever the compatibility setting. */
|
|
38
|
+
fingerprint: string;
|
|
39
|
+
};
|
|
40
|
+
export type Manifest = PreviewInfo & {
|
|
41
|
+
schema: number;
|
|
42
|
+
platform: Platform;
|
|
43
|
+
key: string;
|
|
44
|
+
bundle: string;
|
|
45
|
+
hermesVersion: number | null;
|
|
46
|
+
changelog: string;
|
|
47
|
+
files: ManifestFile[];
|
|
48
|
+
};
|
|
49
|
+
export type IndexEntry = PreviewInfo & {
|
|
50
|
+
/** Changes whenever any file changes, so the app can tell its download is out of date. */
|
|
51
|
+
revision: string;
|
|
52
|
+
size: number;
|
|
53
|
+
changelog: string;
|
|
54
|
+
manifest: string;
|
|
55
|
+
};
|
|
56
|
+
export type PlatformIndex = {
|
|
57
|
+
schema: number;
|
|
58
|
+
platform: Platform;
|
|
59
|
+
key: string;
|
|
60
|
+
compatibility: Compatibility;
|
|
61
|
+
updatedAt: string;
|
|
62
|
+
previews: IndexEntry[];
|
|
63
|
+
};
|
|
64
|
+
export type RootVersion = {
|
|
65
|
+
platform: Platform;
|
|
66
|
+
key: string;
|
|
67
|
+
compatibility: Compatibility;
|
|
68
|
+
appVersion: string;
|
|
69
|
+
buildNumber: string;
|
|
70
|
+
fingerprint: string;
|
|
71
|
+
count: number;
|
|
72
|
+
updatedAt: string;
|
|
73
|
+
index: string;
|
|
74
|
+
previews: {
|
|
75
|
+
id: string;
|
|
76
|
+
title: string;
|
|
77
|
+
publishedAt: string;
|
|
78
|
+
}[];
|
|
79
|
+
};
|
|
80
|
+
export type RootIndex = {
|
|
81
|
+
schema: number;
|
|
82
|
+
updatedAt: string;
|
|
83
|
+
versions: RootVersion[];
|
|
84
|
+
};
|
|
85
|
+
export declare const ROOT_INDEX_KEY = "index.json";
|
|
86
|
+
export declare const fileKey: (sha256: string) => string;
|
|
87
|
+
export declare const platformIndexKey: (platform: Platform, key: string) => string;
|
|
88
|
+
export declare const manifestKey: (platform: Platform, key: string, id: string) => string;
|
|
89
|
+
//# sourceMappingURL=layout.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.util.d.ts","sourceRoot":"","sources":["../../../src/utils/previews/layout.util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// The bucket layout and file formats, shared by the CLI that writes them and the app that reads them.
|
|
2
|
+
//
|
|
3
|
+
// index.json every native build and its previews, for people
|
|
4
|
+
// index/<platform>/<key>.json what one native build can run; the app reads this
|
|
5
|
+
// previews/<platform>/<key>/<id>.json one preview's manifest: its files and changelog
|
|
6
|
+
// files/<sha256> bundle and image blobs, shared between previews
|
|
7
|
+
//
|
|
8
|
+
// <key> names the native build a preview runs on: `version-<app version>` or
|
|
9
|
+
// `fingerprint-<hash>`, depending on the app's `compatibility` setting.
|
|
10
|
+
export const SCHEMA = 1;
|
|
11
|
+
export const PLATFORMS = ["android", "ios"];
|
|
12
|
+
export const DEFAULT_COMPATIBILITY = "appVersion";
|
|
13
|
+
export const isCompatibility = (value) => value === "appVersion" || value === "fingerprint";
|
|
14
|
+
/**
|
|
15
|
+
* The key a build and its previews share. Characters a bucket path should not carry are replaced,
|
|
16
|
+
* so any version string works. app.plugin.js builds the same key; a test keeps the two in step.
|
|
17
|
+
*/
|
|
18
|
+
export const compatibilityKey = (compatibility, value) => `${compatibility === "appVersion" ? "version" : "fingerprint"}-${value.replace(/[^A-Za-z0-9._-]/g, "_")}`;
|
|
19
|
+
/** The setting a key was made with, read back from its prefix. */
|
|
20
|
+
export const compatibilityOfKey = (key) => key.startsWith("version-") ? "appVersion" : "fingerprint";
|
|
21
|
+
/** What `expo export:embed` names the bundle, so a preview folder matches what a build embeds. */
|
|
22
|
+
export const BUNDLE_FILE = {
|
|
23
|
+
android: "index.android.bundle",
|
|
24
|
+
ios: "main.jsbundle",
|
|
25
|
+
};
|
|
26
|
+
export const ROOT_INDEX_KEY = "index.json";
|
|
27
|
+
export const fileKey = (sha256) => `files/${sha256}`;
|
|
28
|
+
export const platformIndexKey = (platform, key) => `index/${platform}/${key}.json`;
|
|
29
|
+
export const manifestKey = (platform, key, id) => `previews/${platform}/${key}/${id}.json`;
|
|
30
|
+
//# sourceMappingURL=layout.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.util.js","sourceRoot":"","sources":["../../../src/utils/previews/layout.util.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,EAAE;AACF,0FAA0F;AAC1F,4FAA4F;AAC5F,0FAA0F;AAC1F,0FAA0F;AAC1F,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AAExE,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC;AAIxB,MAAM,CAAC,MAAM,SAAS,GAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AASxD,MAAM,CAAC,MAAM,qBAAqB,GAAkB,YAAY,CAAC;AAEjE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAc,EAA0B,EAAE,CACxE,KAAK,KAAK,YAAY,IAAI,KAAK,KAAK,aAAa,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,aAA4B,EAC5B,KAAa,EACL,EAAE,CACV,GAAG,aAAa,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,EAAE,CAAC;AAE5G,kEAAkE;AAClE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAW,EAAiB,EAAE,CAC/D,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC;AAE5D,kGAAkG;AAClG,MAAM,CAAC,MAAM,WAAW,GAA6B;IACnD,OAAO,EAAE,sBAAsB;IAC/B,GAAG,EAAE,eAAe;CACrB,CAAC;AAiEF,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC;AAC3C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,SAAS,MAAM,EAAE,CAAC;AAC7D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAkB,EAAE,GAAW,EAAE,EAAE,CAClE,SAAS,QAAQ,IAAI,GAAG,OAAO,CAAC;AAClC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAkB,EAAE,GAAW,EAAE,EAAU,EAAE,EAAE,CACzE,YAAY,QAAQ,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC","sourcesContent":["// The bucket layout and file formats, shared by the CLI that writes them and the app that reads them.\n//\n// index.json every native build and its previews, for people\n// index/<platform>/<key>.json what one native build can run; the app reads this\n// previews/<platform>/<key>/<id>.json one preview's manifest: its files and changelog\n// files/<sha256> bundle and image blobs, shared between previews\n//\n// <key> names the native build a preview runs on: `version-<app version>` or\n// `fingerprint-<hash>`, depending on the app's `compatibility` setting.\n\nexport const SCHEMA = 1;\n\nexport type Platform = \"android\" | \"ios\";\n\nexport const PLATFORMS: Platform[] = [\"android\", \"ios\"];\n\n/**\n * How a preview is matched to a native build. `appVersion` (the default) trusts the app's version:\n * simple, but a native change without a version bump goes unnoticed. `fingerprint` hashes the\n * native side, so any native change makes older previews incompatible.\n */\nexport type Compatibility = \"appVersion\" | \"fingerprint\";\n\nexport const DEFAULT_COMPATIBILITY: Compatibility = \"appVersion\";\n\nexport const isCompatibility = (value: unknown): value is Compatibility =>\n value === \"appVersion\" || value === \"fingerprint\";\n\n/**\n * The key a build and its previews share. Characters a bucket path should not carry are replaced,\n * so any version string works. app.plugin.js builds the same key; a test keeps the two in step.\n */\nexport const compatibilityKey = (\n compatibility: Compatibility,\n value: string,\n): string =>\n `${compatibility === \"appVersion\" ? \"version\" : \"fingerprint\"}-${value.replace(/[^A-Za-z0-9._-]/g, \"_\")}`;\n\n/** The setting a key was made with, read back from its prefix. */\nexport const compatibilityOfKey = (key: string): Compatibility =>\n key.startsWith(\"version-\") ? \"appVersion\" : \"fingerprint\";\n\n/** What `expo export:embed` names the bundle, so a preview folder matches what a build embeds. */\nexport const BUNDLE_FILE: Record<Platform, string> = {\n android: \"index.android.bundle\",\n ios: \"main.jsbundle\",\n};\n\nexport type ManifestFile = { path: string; sha256: string; size: number };\n\n/** Shown to QA in the list, and kept in both the manifest and the index entry. */\nexport type PreviewInfo = {\n id: string;\n title: string;\n branch: string;\n commit: string;\n author: string;\n publishedAt: string;\n appVersion: string;\n buildNumber: string;\n compatibility: Compatibility;\n /** The native build's fingerprint when it was published, whatever the compatibility setting. */\n fingerprint: string;\n};\n\nexport type Manifest = PreviewInfo & {\n schema: number;\n platform: Platform;\n key: string;\n bundle: string;\n hermesVersion: number | null;\n changelog: string;\n files: ManifestFile[];\n};\n\nexport type IndexEntry = PreviewInfo & {\n /** Changes whenever any file changes, so the app can tell its download is out of date. */\n revision: string;\n size: number;\n changelog: string;\n manifest: string;\n};\n\nexport type PlatformIndex = {\n schema: number;\n platform: Platform;\n key: string;\n compatibility: Compatibility;\n updatedAt: string;\n previews: IndexEntry[];\n};\n\nexport type RootVersion = {\n platform: Platform;\n key: string;\n compatibility: Compatibility;\n appVersion: string;\n buildNumber: string;\n fingerprint: string;\n count: number;\n updatedAt: string;\n index: string;\n previews: { id: string; title: string; publishedAt: string }[];\n};\n\nexport type RootIndex = {\n schema: number;\n updatedAt: string;\n versions: RootVersion[];\n};\n\nexport const ROOT_INDEX_KEY = \"index.json\";\nexport const fileKey = (sha256: string) => `files/${sha256}`;\nexport const platformIndexKey = (platform: Platform, key: string) =>\n `index/${platform}/${key}.json`;\nexport const manifestKey = (platform: Platform, key: string, id: string) =>\n `previews/${platform}/${key}/${id}.json`;\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IndexEntry } from "./layout.util";
|
|
2
|
+
import type { LocalPreview } from "../../services/previews/local-previews.service";
|
|
3
|
+
import type { PreviewsState } from "../../stores/previews/previews.store";
|
|
4
|
+
export type PreviewStatus = "available" | "downloading" | "downloaded" | "update-available" | "unpublished" | "broken";
|
|
5
|
+
export type PreviewItem = {
|
|
6
|
+
id: string;
|
|
7
|
+
/** The bucket's entry, or the one saved with the download once it is unpublished. */
|
|
8
|
+
entry: IndexEntry;
|
|
9
|
+
status: PreviewStatus;
|
|
10
|
+
/** 0 to 1 while downloading. */
|
|
11
|
+
progress: number | null;
|
|
12
|
+
active: boolean;
|
|
13
|
+
local: LocalPreview | null;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The list QA sees for this build: everything the bucket offers, plus downloads it no longer lists
|
|
17
|
+
* (unpublished). Downloads for another build go to `incompatible` instead; nothing expires.
|
|
18
|
+
*/
|
|
19
|
+
export declare function previewItems(state: PreviewsState): {
|
|
20
|
+
items: PreviewItem[];
|
|
21
|
+
incompatible: LocalPreview[];
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=preview-items.util.d.ts.map
|