alinea 2.0.0-preview.3 → 2.0.0-preview.4
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/dist/.init/content/pages/welcome.json +1 -1
- package/dist/LICENSES.md +144 -90
- package/dist/adapter/next/DevRemote.js +10 -2
- package/dist/adapter/next/previews.js +1 -0
- package/dist/backend/Handler.js +14 -7
- package/dist/backend/api/BasicAuth.d.ts +1 -1
- package/dist/backend/api/BasicAuth.js +14 -14
- package/dist/backend/api/OAuth2.d.ts +3 -3
- package/dist/backend/api/OAuth2.js +7 -4
- package/dist/bundled.d.ts +96 -25
- package/dist/chunks/{chunk-Y7XOMJOC.js → chunk-CFNRVI3Y.js} +220 -247
- package/dist/chunks/chunk-D6UJHBJJ.js +183 -0
- package/dist/chunks/chunk-TIJTT5ZI.js +228 -0
- package/dist/chunks/{chunk-HFBZMKIN.js → chunk-XMOVGDFI.js} +1 -1
- package/dist/cli/Serve.js +1 -1
- package/dist/cli/bin.js +1 -1
- package/dist/cli/serve/LocalAuth.js +1 -1
- package/dist/cloud/AuthResult.d.ts +2 -0
- package/dist/cloud/CloudHandshake.d.ts +7 -0
- package/dist/cloud/CloudHandshake.js +64 -0
- package/dist/cloud/CloudRemote.d.ts +4 -1
- package/dist/cloud/CloudRemote.js +21 -3
- package/dist/components/Calendar.js +6 -6
- package/dist/components/Checkbox.js +2 -2
- package/dist/components/ComboBox.js +12 -12
- package/dist/components/DatePicker.js +4 -4
- package/dist/components/DateRangePicker.js +4 -4
- package/dist/components/Disclosure.js +6 -6
- package/dist/components/Label.js +6 -6
- package/dist/components/List.js +37 -37
- package/dist/components/Menu.js +4 -4
- package/dist/components/Modal.js +2 -2
- package/dist/components/MultipleSelect.js +23 -23
- package/dist/components/NumberField.js +5 -5
- package/dist/components/ProgressCircle.js +4 -4
- package/dist/components/SearchField.js +7 -7
- package/dist/components/Select.js +6 -6
- package/dist/components/Surface.js +1 -1
- package/dist/components/Table.js +8 -8
- package/dist/components/TextField.js +4 -4
- package/dist/components/TimeField.js +4 -4
- package/dist/components/Toggle.d.ts +1 -1
- package/dist/components/Toggle.js +2 -2
- package/dist/components/Toolbar.js +3 -3
- package/dist/components/Tooltip.js +2 -2
- package/dist/components/Tree.js +6 -6
- package/dist/core/Connection.d.ts +7 -4
- package/dist/core/Entry.d.ts +6 -0
- package/dist/core/Entry.js +10 -0
- package/dist/core/Id.d.ts +1 -0
- package/dist/core/Id.js +8 -0
- package/dist/core/db/Operation.js +4 -3
- package/dist/dashboard/App.js +30 -16
- package/dist/dashboard/StoryProvider.js +2 -2
- package/dist/dashboard/app/AccessDenied.js +3 -3
- package/dist/dashboard/app/ActivityStatus.js +23 -23
- package/dist/dashboard/app/AppShell.js +2 -2
- package/dist/dashboard/app/AppearanceToggle.d.ts +1 -0
- package/dist/dashboard/app/AppearanceToggle.js +43 -0
- package/dist/dashboard/app/AuthView.d.ts +1 -1
- package/dist/dashboard/app/AuthView.js +17 -19
- package/dist/dashboard/app/Badge.js +2 -2
- package/dist/dashboard/app/CompactField.js +17 -17
- package/dist/dashboard/app/DashboardErrorBoundary.js +23 -11
- package/dist/dashboard/app/DashboardLayout.js +15 -8
- package/dist/dashboard/app/DashboardMeta.d.ts +2 -1
- package/dist/dashboard/app/DashboardMeta.js +20 -5
- package/dist/dashboard/app/EntryFields.js +6 -6
- package/dist/dashboard/app/EntryHeader.js +27 -27
- package/dist/dashboard/app/EntryReferences.js +15 -15
- package/dist/dashboard/app/EntrySidebar.js +24 -24
- package/dist/dashboard/app/EntrySidebarPreview.js +20 -19
- package/dist/dashboard/app/EntryTranslationBanner.js +5 -5
- package/dist/dashboard/app/Explorer.js +64 -64
- package/dist/dashboard/app/ExplorerCards.js +46 -46
- package/dist/dashboard/app/ExplorerFileCard.js +19 -19
- package/dist/dashboard/app/ExplorerList.js +20 -20
- package/dist/dashboard/app/ExplorerModal.js +5 -5
- package/dist/dashboard/app/ExplorerPickerContent.js +2 -2
- package/dist/dashboard/app/ExplorerTable.js +63 -63
- package/dist/dashboard/app/ImagePicker.js +7 -7
- package/dist/dashboard/app/LinkPicker.js +17 -22
- package/dist/dashboard/app/LocaleMenu.js +10 -12
- package/dist/dashboard/app/SidebarLayout.js +4 -4
- package/dist/dashboard/app/SidebarTree.js +58 -58
- package/dist/dashboard/app/WorkspaceMenu.d.ts +10 -3
- package/dist/dashboard/app/WorkspaceMenu.js +88 -67
- package/dist/dashboard/app/WorkspaceMenu.stories.d.ts +2 -0
- package/dist/dashboard/app/WorkspaceRoots.d.ts +3 -1
- package/dist/dashboard/app/WorkspaceRoots.js +86 -111
- package/dist/dashboard/app/editor/FileEditor.js +29 -29
- package/dist/dashboard/app/editor/FilePreview.js +6 -6
- package/dist/dashboard/app/editor/MediaAltField.view.js +4 -4
- package/dist/dashboard/app/modals/CreateEntry.js +15 -15
- package/dist/dashboard/app/pages/EntryPage.js +29 -31
- package/dist/dashboard/app/pages/RootPage.js +4 -4
- package/dist/dashboard/app/pages/SplashPage.d.ts +3 -0
- package/dist/dashboard/app/pages/SplashPage.js +414 -0
- package/dist/dashboard/app/pages/UsersPage.js +42 -42
- package/dist/dashboard/app/ui/DashboardModal.js +16 -16
- package/dist/dashboard/app/ui/Rail.js +3 -3
- package/dist/dashboard/app/ui/Sidebar.js +2 -2
- package/dist/dashboard/atoms/ReactiveNode.js +1 -1
- package/dist/dashboard/atoms/activity.js +2 -3
- package/dist/dashboard/atoms/auth.d.ts +2 -0
- package/dist/dashboard/atoms/auth.js +6 -2
- package/dist/dashboard/atoms/config.js +1 -1
- package/dist/dashboard/atoms/core.js +2 -2
- package/dist/dashboard/atoms/create.js +1 -1
- package/dist/dashboard/atoms/dashboard.js +2 -2
- package/dist/dashboard/atoms/editor.js +1 -1
- package/dist/dashboard/atoms/entry.js +2 -2
- package/dist/dashboard/atoms/explorer.d.ts +1 -3
- package/dist/dashboard/atoms/explorer.js +7 -9
- package/dist/dashboard/atoms/graph.d.ts +1 -0
- package/dist/dashboard/atoms/graph.js +7 -2
- package/dist/dashboard/atoms/link.js +2 -2
- package/dist/dashboard/atoms/nav.d.ts +4 -3
- package/dist/dashboard/atoms/nav.js +10 -5
- package/dist/dashboard/atoms/preview.js +1 -1
- package/dist/dashboard/atoms/root.js +2 -2
- package/dist/dashboard/atoms/upload.js +1 -1
- package/dist/dashboard/atoms/user.d.ts +1 -1
- package/dist/dashboard/atoms/user.js +8 -6
- package/dist/dashboard/atoms/utils.js +2 -2
- package/dist/dashboard/boot/Boot.js +2 -4
- package/dist/dashboard/boot/DashboardWorker.js +34 -29
- package/dist/dashboard/editor/UseField.js +6 -6
- package/dist/dashboard/fixture/cms.d.ts +12 -0
- package/dist/dashboard/fixture/cms.js +53 -2
- package/dist/dashboard/hook/UseGraph.js +4 -4
- package/dist/dashboard/hook/UseRoot.js +4 -4
- package/dist/dashboard/hooks.js +16 -16
- package/dist/field/code/CodeField.view.js +12 -12
- package/dist/field/link/LinkField.view.js +56 -56
- package/dist/field/list/ListField.view.js +24 -24
- package/dist/field/localiser/LocalisedField.view.js +76 -5
- package/dist/field/metadata/MetadataField.view.js +19 -19
- package/dist/field/richtext/PickTextLink.js +6 -6
- package/dist/field/richtext/RichTextBlock.js +4 -4
- package/dist/field/richtext/RichTextBlocks.js +1 -1
- package/dist/field/richtext/RichTextExtensions.js +19 -19
- package/dist/field/richtext/RichTextField.view.js +6 -6
- package/dist/field/richtext/RichTextInsertMenu.js +3 -3
- package/dist/field/richtext/RichTextState.js +1 -1
- package/dist/field/text/TextField.view.js +2 -2
- package/dist/index.css +415 -28
- package/dist/preview/RegisterPreview.d.ts +1 -1
- package/dist/preview/RegisterPreview.js +4 -6
- package/dist/preview/react.d.ts +5 -1
- package/dist/preview/react.js +12 -9
- package/package.json +1 -1
- package/dist/chunks/chunk-STAJCW4Z.js +0 -322
- package/dist/chunks/chunk-U4VOHNR2.js +0 -210
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KEY_registerAbortHandler,
|
|
3
|
+
createStore,
|
|
4
|
+
getBuildingBlocks,
|
|
5
|
+
getDefaultStore
|
|
6
|
+
} from "./chunk-CFNRVI3Y.js";
|
|
7
|
+
|
|
8
|
+
// node_modules/jotai/dist/react/Provider.js
|
|
9
|
+
import { createContext, createElement, useContext, useRef } from "react";
|
|
10
|
+
var StoreContext = createContext(void 0);
|
|
11
|
+
function useStore(options) {
|
|
12
|
+
const store = useContext(StoreContext);
|
|
13
|
+
return options?.store || store || getDefaultStore();
|
|
14
|
+
}
|
|
15
|
+
function Provider({ children, store }) {
|
|
16
|
+
const storeRef = useRef(null);
|
|
17
|
+
if (store) {
|
|
18
|
+
return createElement(StoreContext.Provider, { value: store }, children);
|
|
19
|
+
}
|
|
20
|
+
if (storeRef.current === null) {
|
|
21
|
+
storeRef.current = createStore();
|
|
22
|
+
}
|
|
23
|
+
return createElement(StoreContext.Provider, {
|
|
24
|
+
// TODO: If this is not a false positive, consider using useState instead of useRef like https://github.com/pmndrs/jotai/pull/2771
|
|
25
|
+
// eslint-disable-next-line react-hooks/refs
|
|
26
|
+
value: storeRef.current
|
|
27
|
+
}, children);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// node_modules/jotai/dist/react/useAtomValueRaw.js
|
|
31
|
+
import { useDebugValue, useEffect, useReducer } from "react";
|
|
32
|
+
|
|
33
|
+
// node_modules/jotai/dist/react/continuablePromise.js
|
|
34
|
+
var isPromiseLike = (x) => typeof x?.then === "function";
|
|
35
|
+
var continuablePromiseMap = /* @__PURE__ */ new WeakMap();
|
|
36
|
+
var createContinuablePromise = (store, promise, getValue) => {
|
|
37
|
+
const buildingBlocks = getBuildingBlocks(store);
|
|
38
|
+
const registerAbortHandler = buildingBlocks[KEY_registerAbortHandler];
|
|
39
|
+
let continuablePromise = continuablePromiseMap.get(promise);
|
|
40
|
+
if (!continuablePromise) {
|
|
41
|
+
continuablePromise = new Promise((resolve, reject) => {
|
|
42
|
+
let curr = promise;
|
|
43
|
+
const onFulfilled = (me) => (v) => {
|
|
44
|
+
if (curr === me) {
|
|
45
|
+
resolve(v);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const onRejected = (me) => (e) => {
|
|
49
|
+
if (curr === me) {
|
|
50
|
+
reject(e);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const onAbort = () => {
|
|
54
|
+
try {
|
|
55
|
+
const nextValue = getValue();
|
|
56
|
+
if (isPromiseLike(nextValue)) {
|
|
57
|
+
continuablePromiseMap.set(nextValue, continuablePromise);
|
|
58
|
+
curr = nextValue;
|
|
59
|
+
nextValue.then(onFulfilled(nextValue), onRejected(nextValue));
|
|
60
|
+
registerAbortHandler(buildingBlocks, store, nextValue, onAbort);
|
|
61
|
+
} else {
|
|
62
|
+
resolve(nextValue);
|
|
63
|
+
}
|
|
64
|
+
} catch (e) {
|
|
65
|
+
reject(e);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
promise.then(onFulfilled(promise), onRejected(promise));
|
|
69
|
+
registerAbortHandler(buildingBlocks, store, promise, onAbort);
|
|
70
|
+
});
|
|
71
|
+
continuablePromiseMap.set(promise, continuablePromise);
|
|
72
|
+
}
|
|
73
|
+
return continuablePromise;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// node_modules/jotai/dist/react/useAtomValueRaw.js
|
|
77
|
+
function useAtomValueRaw(atom, options) {
|
|
78
|
+
const store = useStore(options);
|
|
79
|
+
const [[valueFromReducer, storeFromReducer, atomFromReducer], rerender] = useReducer((prev) => {
|
|
80
|
+
const nextValue = store.get(atom);
|
|
81
|
+
if (Object.is(prev[0], nextValue) && prev[1] === store && prev[2] === atom) {
|
|
82
|
+
return prev;
|
|
83
|
+
}
|
|
84
|
+
return [nextValue, store, atom];
|
|
85
|
+
}, void 0, () => [store.get(atom), store, atom]);
|
|
86
|
+
let value = valueFromReducer;
|
|
87
|
+
if (storeFromReducer !== store || atomFromReducer !== atom) {
|
|
88
|
+
rerender();
|
|
89
|
+
value = store.get(atom);
|
|
90
|
+
}
|
|
91
|
+
useEffect(() => store.sub(atom, rerender), [store, atom]);
|
|
92
|
+
useDebugValue(value);
|
|
93
|
+
if (isPromiseLike(value)) {
|
|
94
|
+
return createContinuablePromise(store, value, () => store.get(atom));
|
|
95
|
+
}
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// node_modules/jotai/dist/react/useAtomValueRawSync.js
|
|
100
|
+
import { useCallback, useDebugValue as useDebugValue2, useSyncExternalStore } from "react";
|
|
101
|
+
function useAtomValueRawSync(atom, options) {
|
|
102
|
+
const store = useStore(options);
|
|
103
|
+
const getSnapshot = useCallback(() => {
|
|
104
|
+
const value2 = store.get(atom);
|
|
105
|
+
if (isPromiseLike(value2)) {
|
|
106
|
+
return createContinuablePromise(store, value2, () => store.get(atom));
|
|
107
|
+
}
|
|
108
|
+
return value2;
|
|
109
|
+
}, [store, atom]);
|
|
110
|
+
const value = useSyncExternalStore(useCallback((callback) => store.sub(atom, callback), [store, atom]), getSnapshot, getSnapshot);
|
|
111
|
+
useDebugValue2(value);
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// node_modules/jotai/dist/react/useSetAtom.js
|
|
116
|
+
import { useCallback as useCallback2 } from "react";
|
|
117
|
+
function useSetAtom(atom, options) {
|
|
118
|
+
const store = useStore(options);
|
|
119
|
+
const setAtom = useCallback2((...args) => {
|
|
120
|
+
if (process.env.NODE_ENV !== "production" && !("write" in atom)) {
|
|
121
|
+
throw new Error("not writable atom");
|
|
122
|
+
}
|
|
123
|
+
return store.set(atom, ...args);
|
|
124
|
+
}, [store, atom]);
|
|
125
|
+
return setAtom;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// node_modules/jotai/dist/react/useAtomValue.js
|
|
129
|
+
import React from "react";
|
|
130
|
+
var attachPromiseStatus = (promise) => {
|
|
131
|
+
if (!promise.status) {
|
|
132
|
+
promise.status = "pending";
|
|
133
|
+
promise.then((v) => {
|
|
134
|
+
promise.status = "fulfilled";
|
|
135
|
+
promise.value = v;
|
|
136
|
+
}, (e) => {
|
|
137
|
+
promise.status = "rejected";
|
|
138
|
+
promise.reason = e;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
var use = React.use || // A shim for older React versions
|
|
143
|
+
((promise) => {
|
|
144
|
+
if (promise.status === "pending") {
|
|
145
|
+
throw promise;
|
|
146
|
+
} else if (promise.status === "fulfilled") {
|
|
147
|
+
return promise.value;
|
|
148
|
+
} else if (promise.status === "rejected") {
|
|
149
|
+
throw promise.reason;
|
|
150
|
+
} else {
|
|
151
|
+
attachPromiseStatus(promise);
|
|
152
|
+
throw promise;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
function useAtomValue(atom, options) {
|
|
156
|
+
const { unstable_promiseStatus: promiseStatus = !React.use } = options || {};
|
|
157
|
+
const value = useAtomValueRaw(atom, options);
|
|
158
|
+
if (isPromiseLike(value)) {
|
|
159
|
+
if (promiseStatus) {
|
|
160
|
+
attachPromiseStatus(value);
|
|
161
|
+
}
|
|
162
|
+
return use(value);
|
|
163
|
+
}
|
|
164
|
+
return value;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// node_modules/jotai/dist/react/useAtom.js
|
|
168
|
+
function useAtom(atom, options) {
|
|
169
|
+
return [
|
|
170
|
+
useAtomValue(atom, options),
|
|
171
|
+
// We do wrong type assertion here, which results in throwing an error.
|
|
172
|
+
useSetAtom(atom, options)
|
|
173
|
+
];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export {
|
|
177
|
+
useStore,
|
|
178
|
+
Provider,
|
|
179
|
+
useAtomValueRaw,
|
|
180
|
+
useAtomValueRawSync,
|
|
181
|
+
useSetAtom,
|
|
182
|
+
useAtom
|
|
183
|
+
};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import {
|
|
2
|
+
atom
|
|
3
|
+
} from "./chunk-CFNRVI3Y.js";
|
|
4
|
+
|
|
5
|
+
// node_modules/jotai/dist/vanilla/utils/selectAtom.js
|
|
6
|
+
var getCached = (c, m, k) => (m.has(k) ? m : m.set(k, c())).get(k);
|
|
7
|
+
var cache1 = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
var memo3 = (create, dep1, dep2, dep3) => {
|
|
9
|
+
const cache2 = getCached(() => /* @__PURE__ */ new WeakMap(), cache1, dep1);
|
|
10
|
+
const cache3 = getCached(() => /* @__PURE__ */ new WeakMap(), cache2, dep2);
|
|
11
|
+
return getCached(create, cache3, dep3);
|
|
12
|
+
};
|
|
13
|
+
function selectAtom(anAtom, selector, equalityFn = Object.is) {
|
|
14
|
+
return memo3(() => {
|
|
15
|
+
const EMPTY = /* @__PURE__ */ Symbol();
|
|
16
|
+
const selectValue = ([value, prevSlice]) => {
|
|
17
|
+
if (prevSlice === EMPTY) {
|
|
18
|
+
return selector(value);
|
|
19
|
+
}
|
|
20
|
+
const slice = selector(value, prevSlice);
|
|
21
|
+
return equalityFn(prevSlice, slice) ? prevSlice : slice;
|
|
22
|
+
};
|
|
23
|
+
const derivedAtom = atom((get) => {
|
|
24
|
+
const prev = get(derivedAtom);
|
|
25
|
+
const value = get(anAtom);
|
|
26
|
+
return selectValue([value, prev]);
|
|
27
|
+
});
|
|
28
|
+
derivedAtom.init = EMPTY;
|
|
29
|
+
return derivedAtom;
|
|
30
|
+
}, anAtom, selector, equalityFn);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// node_modules/jotai/dist/vanilla/utils/constants.js
|
|
34
|
+
var RESET = /* @__PURE__ */ Symbol(process.env.NODE_ENV !== "production" ? "RESET" : "");
|
|
35
|
+
|
|
36
|
+
// node_modules/jotai/dist/vanilla/utils/atomWithStorage.js
|
|
37
|
+
var isPromiseLike = (x) => typeof x?.then === "function";
|
|
38
|
+
function createJSONStorage(getStringStorage = () => {
|
|
39
|
+
try {
|
|
40
|
+
return window.localStorage;
|
|
41
|
+
} catch (e) {
|
|
42
|
+
if (process.env.NODE_ENV !== "production") {
|
|
43
|
+
if (typeof window !== "undefined") {
|
|
44
|
+
console.warn(e);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
}, options) {
|
|
50
|
+
let lastStr;
|
|
51
|
+
let lastValue;
|
|
52
|
+
const storage = {
|
|
53
|
+
getItem: (key, initialValue) => {
|
|
54
|
+
const parse = (str2) => {
|
|
55
|
+
str2 = str2 || "";
|
|
56
|
+
if (lastStr !== str2) {
|
|
57
|
+
try {
|
|
58
|
+
lastValue = JSON.parse(str2, options?.reviver);
|
|
59
|
+
} catch {
|
|
60
|
+
return initialValue;
|
|
61
|
+
}
|
|
62
|
+
lastStr = str2;
|
|
63
|
+
}
|
|
64
|
+
return lastValue;
|
|
65
|
+
};
|
|
66
|
+
const str = getStringStorage()?.getItem(key) ?? null;
|
|
67
|
+
if (isPromiseLike(str)) {
|
|
68
|
+
return str.then(parse);
|
|
69
|
+
}
|
|
70
|
+
return parse(str);
|
|
71
|
+
},
|
|
72
|
+
setItem: (key, newValue) => getStringStorage()?.setItem(key, JSON.stringify(newValue, options?.replacer)),
|
|
73
|
+
removeItem: (key) => getStringStorage()?.removeItem(key)
|
|
74
|
+
};
|
|
75
|
+
const createHandleSubscribe = (subscriber2) => (key, callback, initialValue) => subscriber2(key, (v) => {
|
|
76
|
+
let newValue;
|
|
77
|
+
try {
|
|
78
|
+
newValue = JSON.parse(v || "", options?.reviver);
|
|
79
|
+
} catch {
|
|
80
|
+
newValue = initialValue;
|
|
81
|
+
}
|
|
82
|
+
callback(newValue);
|
|
83
|
+
});
|
|
84
|
+
let subscriber;
|
|
85
|
+
try {
|
|
86
|
+
subscriber = getStringStorage()?.subscribe;
|
|
87
|
+
} catch {
|
|
88
|
+
}
|
|
89
|
+
if (!subscriber && typeof window !== "undefined" && typeof window.addEventListener === "function" && window.Storage) {
|
|
90
|
+
subscriber = (key, callback) => {
|
|
91
|
+
if (!(getStringStorage() instanceof window.Storage)) {
|
|
92
|
+
return () => {
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const storageEventCallback = (e) => {
|
|
96
|
+
if (e.storageArea === getStringStorage() && e.key === key) {
|
|
97
|
+
callback(e.newValue);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
window.addEventListener("storage", storageEventCallback);
|
|
101
|
+
return () => {
|
|
102
|
+
window.removeEventListener("storage", storageEventCallback);
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (subscriber) {
|
|
107
|
+
storage.subscribe = createHandleSubscribe(subscriber);
|
|
108
|
+
}
|
|
109
|
+
return storage;
|
|
110
|
+
}
|
|
111
|
+
var defaultStorage = createJSONStorage();
|
|
112
|
+
function atomWithStorage(key, initialValue, storage = defaultStorage, options) {
|
|
113
|
+
const getOnInit = options?.getOnInit;
|
|
114
|
+
const baseAtom = atom(getOnInit ? storage.getItem(key, initialValue) : initialValue);
|
|
115
|
+
if (process.env.NODE_ENV !== "production") {
|
|
116
|
+
baseAtom.debugPrivate = true;
|
|
117
|
+
}
|
|
118
|
+
baseAtom.onMount = (setAtom) => {
|
|
119
|
+
setAtom(storage.getItem(key, initialValue));
|
|
120
|
+
return storage.subscribe?.(key, setAtom, initialValue);
|
|
121
|
+
};
|
|
122
|
+
const anAtom = atom((get) => get(baseAtom), (get, set, update) => {
|
|
123
|
+
const nextValue = typeof update === "function" ? update(get(baseAtom)) : update;
|
|
124
|
+
if (nextValue === RESET) {
|
|
125
|
+
set(baseAtom, initialValue);
|
|
126
|
+
return storage.removeItem(key);
|
|
127
|
+
}
|
|
128
|
+
if (isPromiseLike(nextValue)) {
|
|
129
|
+
return nextValue.then((resolvedValue) => {
|
|
130
|
+
set(baseAtom, resolvedValue);
|
|
131
|
+
return storage.setItem(key, resolvedValue);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
set(baseAtom, nextValue);
|
|
135
|
+
return storage.setItem(key, nextValue);
|
|
136
|
+
});
|
|
137
|
+
return anAtom;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// node_modules/jotai/dist/vanilla/utils/unwrap.js
|
|
141
|
+
var getCached2 = (c, m, k) => (m.has(k) ? m : m.set(k, c())).get(k);
|
|
142
|
+
var cache12 = /* @__PURE__ */ new WeakMap();
|
|
143
|
+
var memo2 = (create, dep1, dep2) => {
|
|
144
|
+
const cache2 = getCached2(() => /* @__PURE__ */ new WeakMap(), cache12, dep1);
|
|
145
|
+
return getCached2(create, cache2, dep2);
|
|
146
|
+
};
|
|
147
|
+
var isPromiseLike2 = (p) => typeof p?.then === "function";
|
|
148
|
+
var defaultFallback = () => void 0;
|
|
149
|
+
function unwrap(anAtom, fallback = defaultFallback) {
|
|
150
|
+
return memo2(() => {
|
|
151
|
+
const promiseErrorCache = /* @__PURE__ */ new WeakMap();
|
|
152
|
+
const promiseResultCache = /* @__PURE__ */ new WeakMap();
|
|
153
|
+
const refreshAtom = atom(0);
|
|
154
|
+
const triggerRefreshAtom = atom([]);
|
|
155
|
+
triggerRefreshAtom.INTERNAL_onInit = (store) => {
|
|
156
|
+
store.set(triggerRefreshAtom, [
|
|
157
|
+
() => store.set(refreshAtom, (c) => c + 1)
|
|
158
|
+
]);
|
|
159
|
+
};
|
|
160
|
+
if (process.env.NODE_ENV !== "production") {
|
|
161
|
+
refreshAtom.debugPrivate = true;
|
|
162
|
+
triggerRefreshAtom.debugPrivate = true;
|
|
163
|
+
}
|
|
164
|
+
const promiseAndValueAtom = atom((get) => {
|
|
165
|
+
get(refreshAtom);
|
|
166
|
+
let prev;
|
|
167
|
+
try {
|
|
168
|
+
prev = get(promiseAndValueAtom);
|
|
169
|
+
} catch {
|
|
170
|
+
}
|
|
171
|
+
const promise = get(anAtom);
|
|
172
|
+
if (!isPromiseLike2(promise)) {
|
|
173
|
+
return { v: promise };
|
|
174
|
+
}
|
|
175
|
+
if (promise !== prev?.p) {
|
|
176
|
+
promise.then((v) => {
|
|
177
|
+
promiseResultCache.set(promise, v);
|
|
178
|
+
const [triggerRefresh] = get(triggerRefreshAtom);
|
|
179
|
+
triggerRefresh();
|
|
180
|
+
}, (e) => {
|
|
181
|
+
promiseErrorCache.set(promise, e);
|
|
182
|
+
const [triggerRefresh] = get(triggerRefreshAtom);
|
|
183
|
+
triggerRefresh();
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
if (promiseErrorCache.has(promise)) {
|
|
187
|
+
if (prev && "e" in prev && prev.p === promise) {
|
|
188
|
+
return prev;
|
|
189
|
+
}
|
|
190
|
+
const e = promiseErrorCache.get(promise);
|
|
191
|
+
if (prev && "v" in prev) {
|
|
192
|
+
return { p: promise, e, v: prev.v };
|
|
193
|
+
}
|
|
194
|
+
return { p: promise, e };
|
|
195
|
+
}
|
|
196
|
+
if (promiseResultCache.has(promise)) {
|
|
197
|
+
return {
|
|
198
|
+
p: promise,
|
|
199
|
+
v: promiseResultCache.get(promise)
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
if (prev && "v" in prev) {
|
|
203
|
+
return { p: promise, f: fallback(prev.v), v: prev.v };
|
|
204
|
+
}
|
|
205
|
+
return { p: promise, f: fallback() };
|
|
206
|
+
});
|
|
207
|
+
promiseAndValueAtom.init = void 0;
|
|
208
|
+
if (process.env.NODE_ENV !== "production") {
|
|
209
|
+
promiseAndValueAtom.debugPrivate = true;
|
|
210
|
+
}
|
|
211
|
+
return atom((get) => {
|
|
212
|
+
const state = get(promiseAndValueAtom);
|
|
213
|
+
if ("e" in state) {
|
|
214
|
+
throw state.e;
|
|
215
|
+
}
|
|
216
|
+
if ("f" in state) {
|
|
217
|
+
return state.f;
|
|
218
|
+
}
|
|
219
|
+
return state.v;
|
|
220
|
+
}, (_get, set, ...args) => set(anAtom, ...args));
|
|
221
|
+
}, anAtom, fallback);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export {
|
|
225
|
+
selectAtom,
|
|
226
|
+
atomWithStorage,
|
|
227
|
+
unwrap
|
|
228
|
+
};
|
package/dist/cli/Serve.js
CHANGED
package/dist/cli/bin.js
CHANGED
|
@@ -220,7 +220,7 @@ var lib_default2 = (e, t2) => new o(e, t2);
|
|
|
220
220
|
// package.json
|
|
221
221
|
var package_default = {
|
|
222
222
|
name: "alinea",
|
|
223
|
-
version: "2.0.0-preview.
|
|
223
|
+
version: "2.0.0-preview.4",
|
|
224
224
|
description: "Headless git-based CMS",
|
|
225
225
|
repository: "github:alineacms/alinea",
|
|
226
226
|
license: "MIT",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BackendCapabilities } from 'alinea/core/Connection';
|
|
1
2
|
import type { User } from 'alinea/core/User';
|
|
2
3
|
export declare enum AuthResultType {
|
|
3
4
|
Authenticated = 0,
|
|
@@ -8,6 +9,7 @@ export declare enum AuthResultType {
|
|
|
8
9
|
export type AuthResult = {
|
|
9
10
|
type: AuthResultType.Authenticated;
|
|
10
11
|
user: User;
|
|
12
|
+
capabilities?: BackendCapabilities;
|
|
11
13
|
} | {
|
|
12
14
|
type: AuthResultType.UnAuthenticated;
|
|
13
15
|
redirect: string;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import "../chunks/chunk-CQ52GEHY.js";
|
|
2
|
+
|
|
3
|
+
// src/cloud/CloudHandshake.ts
|
|
4
|
+
import { decode, verify } from "alinea/core/util/JWT";
|
|
5
|
+
import { isRecord } from "alinea/core/util/Objects";
|
|
6
|
+
import { cloudConfig } from "./CloudConfig.js";
|
|
7
|
+
var keysPromise;
|
|
8
|
+
var keysExpireAt = 0;
|
|
9
|
+
var lastForcedRefreshAt = 0;
|
|
10
|
+
var keyCacheLifetime = 5 * 60 * 1e3;
|
|
11
|
+
var forcedRefreshInterval = 60 * 1e3;
|
|
12
|
+
async function verifyCloudHandshake(token, options) {
|
|
13
|
+
const { header } = decode(token);
|
|
14
|
+
if (header.alg !== "RS256" || typeof header.kid !== "string")
|
|
15
|
+
throw new Error("Invalid handshake token header");
|
|
16
|
+
let key = (await cloudKeys()).find((key2) => key2.kid === header.kid);
|
|
17
|
+
if (!key) {
|
|
18
|
+
key = (await refreshCloudKeys()).find((key2) => key2.kid === header.kid);
|
|
19
|
+
}
|
|
20
|
+
if (!key) throw new Error("Unknown handshake signing key");
|
|
21
|
+
const payload = await verify(token, key, { algorithms: ["RS256"] });
|
|
22
|
+
if (!isRecord(payload) || payload.purpose !== "handshake" || payload.handshake_id !== options.handshakeId || payload.aud !== options.clientId || payload.iss !== normalizedCloudUrl() || payload.origin !== options.origin || typeof payload.project !== "string" || typeof payload.iat !== "number" || typeof payload.exp !== "number") {
|
|
23
|
+
throw new Error("Invalid handshake token claims");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function cloudKeys() {
|
|
27
|
+
if (keysPromise && (keysExpireAt === 0 || Date.now() < keysExpireAt))
|
|
28
|
+
return keysPromise;
|
|
29
|
+
return loadCloudKeys();
|
|
30
|
+
}
|
|
31
|
+
function refreshCloudKeys() {
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
if (keysPromise && keysExpireAt === 0) return keysPromise;
|
|
34
|
+
if (keysPromise && now - lastForcedRefreshAt < forcedRefreshInterval)
|
|
35
|
+
return keysPromise;
|
|
36
|
+
lastForcedRefreshAt = now;
|
|
37
|
+
return loadCloudKeys();
|
|
38
|
+
}
|
|
39
|
+
function loadCloudKeys() {
|
|
40
|
+
keysExpireAt = 0;
|
|
41
|
+
keysPromise = fetch(cloudConfig.jwks).then(async (response) => {
|
|
42
|
+
if (!response.ok)
|
|
43
|
+
throw new Error(`Could not load handshake keys: ${response.status}`);
|
|
44
|
+
const body = await response.json();
|
|
45
|
+
if (!isRecord(body) || !Array.isArray(body.keys))
|
|
46
|
+
throw new Error("Invalid handshake key response");
|
|
47
|
+
keysExpireAt = Date.now() + keyCacheLifetime;
|
|
48
|
+
return body.keys.filter(isCloudKey);
|
|
49
|
+
}).catch((cause) => {
|
|
50
|
+
keysPromise = void 0;
|
|
51
|
+
keysExpireAt = 0;
|
|
52
|
+
throw cause;
|
|
53
|
+
});
|
|
54
|
+
return keysPromise;
|
|
55
|
+
}
|
|
56
|
+
function isCloudKey(value) {
|
|
57
|
+
return isRecord(value) && typeof value.kid === "string";
|
|
58
|
+
}
|
|
59
|
+
function normalizedCloudUrl() {
|
|
60
|
+
return cloudConfig.url.replace(/\/$/, "");
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
verifyCloudHandshake
|
|
64
|
+
};
|
|
@@ -10,12 +10,15 @@ import type { User, UserInput } from 'alinea/core/User';
|
|
|
10
10
|
export declare class CloudRemote extends OAuth2 implements RemoteConnection {
|
|
11
11
|
#private;
|
|
12
12
|
constructor(context: RequestContext, config: Config);
|
|
13
|
+
capabilities(): Promise<{
|
|
14
|
+
users: boolean;
|
|
15
|
+
}>;
|
|
13
16
|
getTreeIfDifferent(sha: string): Promise<ReadonlyTree | undefined>;
|
|
14
17
|
getBlobs(shas: ReadonlyArray<string>, options?: GetBlobsOptions): AsyncGenerator<[sha: string, blob: Uint8Array]>;
|
|
15
18
|
write(request: CommitRequest): Promise<{
|
|
16
19
|
sha: string;
|
|
17
20
|
}>;
|
|
18
|
-
authenticate(request: Request, options
|
|
21
|
+
authenticate(request: Request, options: AuthOptions): Promise<globalThis.Response>;
|
|
19
22
|
prepareUpload(file: string, metadata?: UploadMetadata): Promise<{
|
|
20
23
|
entryId: string;
|
|
21
24
|
location: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
package_default
|
|
3
|
-
} from "../chunks/chunk-
|
|
3
|
+
} from "../chunks/chunk-XMOVGDFI.js";
|
|
4
4
|
import "../chunks/chunk-CQ52GEHY.js";
|
|
5
5
|
|
|
6
6
|
// src/cloud/CloudRemote.ts
|
|
@@ -20,6 +20,7 @@ import { Workspace } from "alinea/core/Workspace";
|
|
|
20
20
|
import { Response } from "@alinea/iso";
|
|
21
21
|
import { AuthResultType } from "./AuthResult.js";
|
|
22
22
|
import { cloudConfig } from "./CloudConfig.js";
|
|
23
|
+
import { verifyCloudHandshake } from "./CloudHandshake.js";
|
|
23
24
|
var CloudRemote = class extends OAuth2 {
|
|
24
25
|
#context;
|
|
25
26
|
#config;
|
|
@@ -42,6 +43,9 @@ var CloudRemote = class extends OAuth2 {
|
|
|
42
43
|
this.#context = context;
|
|
43
44
|
this.#config = config;
|
|
44
45
|
}
|
|
46
|
+
async capabilities() {
|
|
47
|
+
return { users: false };
|
|
48
|
+
}
|
|
45
49
|
async getTreeIfDifferent(sha) {
|
|
46
50
|
const ctx = this.#context;
|
|
47
51
|
return parseOutcome(
|
|
@@ -122,13 +126,27 @@ var CloudRemote = class extends OAuth2 {
|
|
|
122
126
|
// The cloud server will request a handshake confirmation on this route
|
|
123
127
|
case AuthAction.Handshake: {
|
|
124
128
|
const handShakeId = url.searchParams.get("handshake_id");
|
|
125
|
-
|
|
129
|
+
const handshakeToken = url.searchParams.get("handshake_token");
|
|
130
|
+
if (!handShakeId || !handshakeToken)
|
|
126
131
|
throw new HttpError(
|
|
127
132
|
400,
|
|
128
|
-
"Provide
|
|
133
|
+
"Provide valid handshake credentials to initiate handshake"
|
|
129
134
|
);
|
|
135
|
+
const clientId = ctx.apiKey.split("_")[1];
|
|
136
|
+
if (!clientId)
|
|
137
|
+
throw new HttpError(401, "A Cloud API key is required for handshake");
|
|
138
|
+
try {
|
|
139
|
+
await verifyCloudHandshake(handshakeToken, {
|
|
140
|
+
clientId,
|
|
141
|
+
handshakeId: handShakeId,
|
|
142
|
+
origin: new URL(ctx.handlerUrl).origin
|
|
143
|
+
});
|
|
144
|
+
} catch (cause) {
|
|
145
|
+
throw new HttpError(401, "Invalid handshake token", { cause });
|
|
146
|
+
}
|
|
130
147
|
const body = {
|
|
131
148
|
handshake_id: handShakeId,
|
|
149
|
+
handshake_token: handshakeToken,
|
|
132
150
|
status: {
|
|
133
151
|
version: package_default.version,
|
|
134
152
|
roles: entries(this.#config.roles ?? {}).map(([name, role]) => {
|
|
@@ -27,17 +27,17 @@ import {
|
|
|
27
27
|
|
|
28
28
|
// src/components/Calendar.module.css
|
|
29
29
|
var Calendar_default = {
|
|
30
|
-
"Calendar-
|
|
31
|
-
"
|
|
30
|
+
"Calendar-button": "alinea-Calendar-button",
|
|
31
|
+
"CalendarButton": "alinea-Calendar-button",
|
|
32
32
|
"Calendar-grid": "alinea-Calendar-grid",
|
|
33
33
|
"CalendarGrid": "alinea-Calendar-grid",
|
|
34
|
+
"Calendar-cell": "alinea-Calendar-cell",
|
|
35
|
+
"CalendarCell": "alinea-Calendar-cell",
|
|
36
|
+
"Calendar": "alinea-Calendar",
|
|
34
37
|
"Calendar-header": "alinea-Calendar-header",
|
|
35
38
|
"CalendarHeader": "alinea-Calendar-header",
|
|
36
|
-
"Calendar-button": "alinea-Calendar-button",
|
|
37
|
-
"CalendarButton": "alinea-Calendar-button",
|
|
38
39
|
"Calendar-heading": "alinea-Calendar-heading",
|
|
39
|
-
"CalendarHeading": "alinea-Calendar-heading"
|
|
40
|
-
"Calendar": "alinea-Calendar"
|
|
40
|
+
"CalendarHeading": "alinea-Calendar-heading"
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
// src/components/Calendar.tsx
|
|
@@ -16,11 +16,11 @@ import "../chunks/chunk-CQ52GEHY.js";
|
|
|
16
16
|
|
|
17
17
|
// src/components/Checkbox.module.css
|
|
18
18
|
var Checkbox_default = {
|
|
19
|
+
"Checkbox": "alinea-Checkbox",
|
|
19
20
|
"Checkbox-box": "alinea-Checkbox-box",
|
|
20
21
|
"CheckboxBox": "alinea-Checkbox-box",
|
|
21
22
|
"Checkbox-mark": "alinea-Checkbox-mark",
|
|
22
|
-
"CheckboxMark": "alinea-Checkbox-mark"
|
|
23
|
-
"Checkbox": "alinea-Checkbox"
|
|
23
|
+
"CheckboxMark": "alinea-Checkbox-mark"
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
// src/components/Checkbox.tsx
|
|
@@ -29,24 +29,24 @@ import {
|
|
|
29
29
|
|
|
30
30
|
// src/components/ComboBox.module.css
|
|
31
31
|
var ComboBox_default = {
|
|
32
|
-
"ComboBoxItem": "alinea-ComboBoxItem",
|
|
33
|
-
"ComboBoxTrigger-button-arrow": "alinea-ComboBoxTrigger-button-arrow",
|
|
34
|
-
"ComboBoxTriggerButtonArrow": "alinea-ComboBoxTrigger-button-arrow",
|
|
35
|
-
"ComboBoxTrigger-button": "alinea-ComboBoxTrigger-button",
|
|
36
|
-
"ComboBoxTriggerButton": "alinea-ComboBoxTrigger-button",
|
|
37
|
-
"ComboBoxTrigger": "alinea-ComboBoxTrigger",
|
|
38
|
-
"ComboBoxTrigger-actions": "alinea-ComboBoxTrigger-actions",
|
|
39
|
-
"ComboBoxTriggerActions": "alinea-ComboBoxTrigger-actions",
|
|
40
32
|
"ComboBoxPopover-listbox": "alinea-ComboBoxPopover-listbox",
|
|
41
33
|
"ComboBoxPopoverListbox": "alinea-ComboBoxPopover-listbox",
|
|
42
|
-
"ComboBoxClear": "alinea-ComboBoxClear",
|
|
43
|
-
"ComboBoxTrigger-input": "alinea-ComboBoxTrigger-input",
|
|
44
|
-
"ComboBoxTriggerInput": "alinea-ComboBoxTrigger-input",
|
|
45
34
|
"ComboBoxItem-check": "alinea-ComboBoxItem-check",
|
|
46
35
|
"ComboBoxItemCheck": "alinea-ComboBoxItem-check",
|
|
36
|
+
"ComboBoxTrigger-actions": "alinea-ComboBoxTrigger-actions",
|
|
37
|
+
"ComboBoxTriggerActions": "alinea-ComboBoxTrigger-actions",
|
|
38
|
+
"ComboBox": "alinea-ComboBox",
|
|
47
39
|
"ComboBoxTrigger-button-value": "alinea-ComboBoxTrigger-button-value",
|
|
48
40
|
"ComboBoxTriggerButtonValue": "alinea-ComboBoxTrigger-button-value",
|
|
49
|
-
"
|
|
41
|
+
"ComboBoxTrigger-button-arrow": "alinea-ComboBoxTrigger-button-arrow",
|
|
42
|
+
"ComboBoxTriggerButtonArrow": "alinea-ComboBoxTrigger-button-arrow",
|
|
43
|
+
"ComboBoxTrigger": "alinea-ComboBoxTrigger",
|
|
44
|
+
"ComboBoxClear": "alinea-ComboBoxClear",
|
|
45
|
+
"ComboBoxItem": "alinea-ComboBoxItem",
|
|
46
|
+
"ComboBoxTrigger-button": "alinea-ComboBoxTrigger-button",
|
|
47
|
+
"ComboBoxTriggerButton": "alinea-ComboBoxTrigger-button",
|
|
48
|
+
"ComboBoxTrigger-input": "alinea-ComboBoxTrigger-input",
|
|
49
|
+
"ComboBoxTriggerInput": "alinea-ComboBoxTrigger-input"
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
// src/components/ComboBox.tsx
|