alinea 1.4.0-preview.0 → 1.4.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/dist/.init/content/pages/welcome.json +1 -1
- package/dist/LICENSES.md +72 -72
- package/dist/backend/api/GithubApi.d.ts +0 -1
- package/dist/backend/api/GithubApi.js +181 -153
- package/dist/chunks/{chunk-LIA6NPBB.js → chunk-OO7VJEA4.js} +1 -1
- package/dist/cli/Serve.js +1 -1
- package/dist/cli/bin.js +1 -1
- package/dist/cli/serve/GitHistory.js +30 -28
- package/dist/cli/util/CommitMessage.d.ts +4 -0
- package/dist/cli/util/CommitMessage.js +16 -0
- package/dist/cli/util/CommitMessage.test.d.ts +1 -0
- package/dist/cloud/CloudRemote.js +1 -1
- package/dist/core/db/EntryTransaction.js +13 -7
- package/dist/core/source/GithubSource.d.ts +2 -0
- package/dist/core/source/GithubSource.js +9 -3
- package/dist/core/source/Tree.js +2 -1
- package/dist/core/util/EntryFilenames.d.ts +1 -0
- package/dist/core/util/EntryFilenames.js +12 -0
- package/dist/dashboard/Routes.d.ts +2 -2
- package/dist/dashboard/atoms/DashboardAtoms.js +1 -1
- package/dist/dashboard/atoms/DbAtoms.js +3 -3
- package/dist/dashboard/atoms/EntryEditorAtoms.d.ts +5 -5
- package/dist/dashboard/atoms/EntryEditorAtoms.js +7 -7
- package/dist/dashboard/atoms/EntrySummaryAtoms.js +3 -3
- package/dist/dashboard/atoms/LocationAtoms.js +3 -3
- package/dist/dashboard/atoms/NavigationAtoms.js +3 -3
- package/dist/dashboard/view/entry/EntryHeader.js +14 -13
- package/dist/dashboard/view/entry/EntryPreview.js +3 -3
- package/dist/field/list/ListField.view.js +3 -3
- package/package.json +1 -1
package/dist/LICENSES.md
CHANGED
|
@@ -81,29 +81,6 @@ SOFTWARE.
|
|
|
81
81
|
|
|
82
82
|
===
|
|
83
83
|
|
|
84
|
-
# htmlparser2@9.1.0 (MIT)
|
|
85
|
-
|
|
86
|
-
Copyright 2010, 2011, Chris Winberry <chris@winberry.net>. All rights reserved.
|
|
87
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
88
|
-
of this software and associated documentation files (the "Software"), to
|
|
89
|
-
deal in the Software without restriction, including without limitation the
|
|
90
|
-
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
91
|
-
sell copies of the Software, and to permit persons to whom the Software is
|
|
92
|
-
furnished to do so, subject to the following conditions:
|
|
93
|
-
|
|
94
|
-
The above copyright notice and this permission notice shall be included in
|
|
95
|
-
all copies or substantial portions of the Software.
|
|
96
|
-
|
|
97
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
98
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
99
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
100
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
101
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
102
|
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
103
|
-
IN THE SOFTWARE.
|
|
104
|
-
|
|
105
|
-
===
|
|
106
|
-
|
|
107
84
|
# react-query@3.39.3 (MIT)
|
|
108
85
|
|
|
109
86
|
MIT License
|
|
@@ -131,7 +108,30 @@ SOFTWARE.
|
|
|
131
108
|
|
|
132
109
|
===
|
|
133
110
|
|
|
134
|
-
#
|
|
111
|
+
# htmlparser2@9.1.0 (MIT)
|
|
112
|
+
|
|
113
|
+
Copyright 2010, 2011, Chris Winberry <chris@winberry.net>. All rights reserved.
|
|
114
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
115
|
+
of this software and associated documentation files (the "Software"), to
|
|
116
|
+
deal in the Software without restriction, including without limitation the
|
|
117
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
118
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
|
119
|
+
furnished to do so, subject to the following conditions:
|
|
120
|
+
|
|
121
|
+
The above copyright notice and this permission notice shall be included in
|
|
122
|
+
all copies or substantial portions of the Software.
|
|
123
|
+
|
|
124
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
125
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
126
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
127
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
128
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
129
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
130
|
+
IN THE SOFTWARE.
|
|
131
|
+
|
|
132
|
+
===
|
|
133
|
+
|
|
134
|
+
# domhandler@5.0.3 (BSD-2-Clause)
|
|
135
135
|
|
|
136
136
|
Copyright (c) Felix Böhm
|
|
137
137
|
All rights reserved.
|
|
@@ -148,7 +148,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
148
148
|
|
|
149
149
|
===
|
|
150
150
|
|
|
151
|
-
#
|
|
151
|
+
# entities@4.5.0 (BSD-2-Clause)
|
|
152
152
|
|
|
153
153
|
Copyright (c) Felix Böhm
|
|
154
154
|
All rights reserved.
|
|
@@ -165,7 +165,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
165
165
|
|
|
166
166
|
===
|
|
167
167
|
|
|
168
|
-
#
|
|
168
|
+
# domutils@3.1.0 (BSD-2-Clause)
|
|
169
169
|
|
|
170
170
|
Copyright (c) Felix Böhm
|
|
171
171
|
All rights reserved.
|
|
@@ -440,6 +440,23 @@ SOFTWARE.
|
|
|
440
440
|
limitations under the License.
|
|
441
441
|
|
|
442
442
|
|
|
443
|
+
===
|
|
444
|
+
|
|
445
|
+
# dom-serializer@2.0.0 (MIT)
|
|
446
|
+
|
|
447
|
+
License
|
|
448
|
+
|
|
449
|
+
(The MIT License)
|
|
450
|
+
|
|
451
|
+
Copyright (c) 2014 The cheeriojs contributors
|
|
452
|
+
|
|
453
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
454
|
+
|
|
455
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
456
|
+
|
|
457
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
458
|
+
|
|
459
|
+
|
|
443
460
|
===
|
|
444
461
|
|
|
445
462
|
# react-is@16.13.1 (MIT)
|
|
@@ -467,23 +484,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
467
484
|
SOFTWARE.
|
|
468
485
|
|
|
469
486
|
|
|
470
|
-
===
|
|
471
|
-
|
|
472
|
-
# dom-serializer@2.0.0 (MIT)
|
|
473
|
-
|
|
474
|
-
License
|
|
475
|
-
|
|
476
|
-
(The MIT License)
|
|
477
|
-
|
|
478
|
-
Copyright (c) 2014 The cheeriojs contributors
|
|
479
|
-
|
|
480
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
481
|
-
|
|
482
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
483
|
-
|
|
484
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
485
|
-
|
|
486
|
-
|
|
487
487
|
===
|
|
488
488
|
|
|
489
489
|
# @headless-tree/core@0.0.15 (MIT)
|
|
@@ -553,7 +553,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
553
553
|
|
|
554
554
|
===
|
|
555
555
|
|
|
556
|
-
# @react-aria/
|
|
556
|
+
# @react-aria/interactions@3.23.0 (Apache-2.0)
|
|
557
557
|
|
|
558
558
|
Apache License
|
|
559
559
|
Version 2.0, January 2004
|
|
@@ -760,7 +760,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
760
760
|
|
|
761
761
|
===
|
|
762
762
|
|
|
763
|
-
# @react-aria/
|
|
763
|
+
# @react-aria/focus@3.19.1 (Apache-2.0)
|
|
764
764
|
|
|
765
765
|
Apache License
|
|
766
766
|
Version 2.0, January 2004
|
|
@@ -1585,33 +1585,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
1585
1585
|
See the License for the specific language governing permissions and
|
|
1586
1586
|
limitations under the License.
|
|
1587
1587
|
|
|
1588
|
-
===
|
|
1589
|
-
|
|
1590
|
-
# @tanstack/virtual-core@3.10.6 (MIT)
|
|
1591
|
-
|
|
1592
|
-
MIT License
|
|
1593
|
-
|
|
1594
|
-
Copyright (c) 2021-present Tanner Linsley
|
|
1595
|
-
|
|
1596
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1597
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
1598
|
-
in the Software without restriction, including without limitation the rights
|
|
1599
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1600
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
1601
|
-
furnished to do so, subject to the following conditions:
|
|
1602
|
-
|
|
1603
|
-
The above copyright notice and this permission notice shall be included in all
|
|
1604
|
-
copies or substantial portions of the Software.
|
|
1605
|
-
|
|
1606
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1607
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1608
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1609
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1610
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1611
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1612
|
-
SOFTWARE.
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
1588
|
===
|
|
1616
1589
|
|
|
1617
1590
|
# @react-stately/utils@3.10.5 (Apache-2.0)
|
|
@@ -1817,3 +1790,30 @@ SOFTWARE.
|
|
|
1817
1790
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1818
1791
|
See the License for the specific language governing permissions and
|
|
1819
1792
|
limitations under the License.
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
===
|
|
1796
|
+
|
|
1797
|
+
# @tanstack/virtual-core@3.10.6 (MIT)
|
|
1798
|
+
|
|
1799
|
+
MIT License
|
|
1800
|
+
|
|
1801
|
+
Copyright (c) 2021-present Tanner Linsley
|
|
1802
|
+
|
|
1803
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1804
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
1805
|
+
in the Software without restriction, including without limitation the rights
|
|
1806
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1807
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
1808
|
+
furnished to do so, subject to the following conditions:
|
|
1809
|
+
|
|
1810
|
+
The above copyright notice and this permission notice shall be included in all
|
|
1811
|
+
copies or substantial portions of the Software.
|
|
1812
|
+
|
|
1813
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1814
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1815
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1816
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1817
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1818
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1819
|
+
SOFTWARE.
|
|
@@ -3,7 +3,6 @@ import type { EntryRecord } from 'alinea/core/EntryRecord';
|
|
|
3
3
|
import type { CommitRequest } from 'alinea/core/db/CommitRequest';
|
|
4
4
|
import { GithubSource, type GithubSourceOptions } from 'alinea/core/source/GithubSource';
|
|
5
5
|
export interface GithubOptions extends GithubSourceOptions {
|
|
6
|
-
rootDir: string;
|
|
7
6
|
author?: {
|
|
8
7
|
name: string;
|
|
9
8
|
email: string;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import "../../chunks/chunk-NZLE2WMY.js";
|
|
2
2
|
|
|
3
3
|
// src/backend/api/GithubApi.ts
|
|
4
|
+
import { parseCoAuthoredBy } from "alinea/cli/util/CommitMessage";
|
|
4
5
|
import { HttpError } from "alinea/core/HttpError";
|
|
5
6
|
import {
|
|
6
7
|
GithubSource
|
|
7
8
|
} from "alinea/core/source/GithubSource";
|
|
8
9
|
import { ShaMismatchError } from "alinea/core/source/ShaMismatchError";
|
|
9
10
|
import { base64, btoa } from "alinea/core/util/Encoding";
|
|
11
|
+
import { fileVersions } from "alinea/core/util/EntryFilenames";
|
|
10
12
|
import { join } from "alinea/core/util/Paths";
|
|
11
13
|
var GithubApi = class extends GithubSource {
|
|
12
14
|
#options;
|
|
@@ -15,7 +17,7 @@ var GithubApi = class extends GithubSource {
|
|
|
15
17
|
this.#options = options;
|
|
16
18
|
}
|
|
17
19
|
async write(request) {
|
|
18
|
-
const currentCommit = await getLatestCommitOid(
|
|
20
|
+
const currentCommit = await this.#getLatestCommitOid();
|
|
19
21
|
const currentSha = await this.shaAt(currentCommit);
|
|
20
22
|
if (currentSha !== request.fromSha)
|
|
21
23
|
throw new ShaMismatchError(currentSha, request.fromSha);
|
|
@@ -26,8 +28,7 @@ var GithubApi = class extends GithubSource {
|
|
|
26
28
|
|
|
27
29
|
Co-authored-by: ${author.name} <${author.email}>`;
|
|
28
30
|
}
|
|
29
|
-
const newCommit = await applyChangesToRepo(
|
|
30
|
-
this.#options,
|
|
31
|
+
const newCommit = await this.#applyChangesToRepo(
|
|
31
32
|
currentCommit,
|
|
32
33
|
request.changes,
|
|
33
34
|
commitMessage
|
|
@@ -35,79 +36,108 @@ Co-authored-by: ${author.name} <${author.email}>`;
|
|
|
35
36
|
return { sha: await this.shaAt(newCommit) };
|
|
36
37
|
}
|
|
37
38
|
async revisions(file) {
|
|
38
|
-
return getFileCommitHistory(
|
|
39
|
+
return this.#getFileCommitHistory(file);
|
|
39
40
|
}
|
|
40
41
|
async revisionData(file, revisionId) {
|
|
41
|
-
const content = await getFileContentAtCommit(
|
|
42
|
-
this.#options,
|
|
43
|
-
file,
|
|
44
|
-
revisionId
|
|
45
|
-
);
|
|
42
|
+
const content = await this.#getFileContentAtCommit(file, revisionId);
|
|
46
43
|
try {
|
|
47
44
|
return content ? JSON.parse(content) : void 0;
|
|
48
45
|
} catch (error) {
|
|
49
46
|
return void 0;
|
|
50
47
|
}
|
|
51
48
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
49
|
+
async #graphQL(query, variables, token) {
|
|
50
|
+
return fetch("https://api.github.com/graphql", {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
Authorization: `Bearer ${token}`,
|
|
54
|
+
"Content-Type": "application/json"
|
|
55
|
+
},
|
|
56
|
+
body: JSON.stringify({ query, variables })
|
|
57
|
+
}).then(async (response) => {
|
|
58
|
+
if (response.ok) return response.json();
|
|
59
|
+
throw new HttpError(response.status, await response.text());
|
|
60
|
+
}).then((result) => {
|
|
61
|
+
if (Array.isArray(result.errors) && result.errors.length > 0) {
|
|
62
|
+
const message = result.errors.map((e) => e.message).join("; ");
|
|
63
|
+
console.trace(result.errors);
|
|
64
|
+
throw new Error(message);
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async #getFileCommitHistory(file) {
|
|
70
|
+
const { owner, repo, branch, authToken, rootDir } = this.#options;
|
|
71
|
+
const seen = /* @__PURE__ */ new Set();
|
|
72
|
+
const queue = fileVersions(file);
|
|
73
|
+
const allRevisions = Array();
|
|
74
|
+
const maxRequests = 3;
|
|
75
|
+
let requestCount = 0;
|
|
76
|
+
while (queue.length) {
|
|
77
|
+
if (requestCount === maxRequests) break;
|
|
78
|
+
requestCount++;
|
|
79
|
+
const versions = [...queue].filter((v) => !seen.has(v));
|
|
80
|
+
for (const v of versions) seen.add(v);
|
|
81
|
+
queue.length = 0;
|
|
82
|
+
const aliasMap = versions.map((v, idx) => ({
|
|
83
|
+
alias: `file${idx}`,
|
|
84
|
+
version: v,
|
|
85
|
+
path: join(rootDir, v)
|
|
86
|
+
}));
|
|
87
|
+
const query = aliasMap.map(
|
|
88
|
+
({ alias, path }) => `
|
|
89
|
+
${alias}: history(path: "${path}", first: 100) {
|
|
90
|
+
nodes {
|
|
91
|
+
oid
|
|
92
|
+
committedDate
|
|
93
|
+
message
|
|
94
|
+
author { name email }
|
|
95
|
+
}
|
|
96
|
+
}`
|
|
97
|
+
).join("");
|
|
98
|
+
const gql = `
|
|
99
|
+
query GetFileHistory($owner: String!, $repo: String!, $branch: String!) {
|
|
100
|
+
repository(owner: $owner, name: $repo) {
|
|
101
|
+
ref(qualifiedName: $branch) {
|
|
102
|
+
target { ... on Commit {${query}} }
|
|
91
103
|
}
|
|
92
104
|
}
|
|
105
|
+
}`;
|
|
106
|
+
const result = await this.#graphQL(gql, { owner, repo, branch }, authToken);
|
|
107
|
+
for (const { alias, version, path } of aliasMap) {
|
|
108
|
+
const commits = result.data.repository.ref.target[alias]?.nodes || [];
|
|
109
|
+
if (!commits.length) continue;
|
|
110
|
+
allRevisions.push(
|
|
111
|
+
...commits.map((commit) => ({
|
|
112
|
+
ref: commit.oid,
|
|
113
|
+
createdAt: new Date(commit.committedDate).getTime(),
|
|
114
|
+
file: version,
|
|
115
|
+
user: parseCoAuthoredBy(commit.message) ?? (commit.author ? { name: commit.author.name, email: commit.author.email } : void 0),
|
|
116
|
+
description: commit.message
|
|
117
|
+
}))
|
|
118
|
+
);
|
|
119
|
+
const earliest = commits[commits.length - 1].oid;
|
|
120
|
+
const res = await fetch(
|
|
121
|
+
`https://api.github.com/repos/${owner}/${repo}/commits/${earliest}`,
|
|
122
|
+
{ headers: { Authorization: `Bearer ${authToken}` } }
|
|
123
|
+
);
|
|
124
|
+
if (!res.ok) throw new HttpError(res.status, await res.text());
|
|
125
|
+
const commitData = await res.json();
|
|
126
|
+
const fileEntry = Array.isArray(commitData.files) ? commitData.files.find((f) => f.filename === path) : void 0;
|
|
127
|
+
const prev = fileEntry?.previous_filename;
|
|
128
|
+
if (prev) {
|
|
129
|
+
const prefix = rootDir ? `${rootDir}/` : "";
|
|
130
|
+
const relative = prev.startsWith(prefix) ? prev.slice(prefix.length) : prev;
|
|
131
|
+
queue.push(...fileVersions(relative));
|
|
93
132
|
}
|
|
94
133
|
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
createdAt: new Date(commit.committedDate).getTime(),
|
|
103
|
-
file,
|
|
104
|
-
user: commit.author ? { name: commit.author.name, email: commit.author.email } : void 0,
|
|
105
|
-
description: commit.message
|
|
106
|
-
}));
|
|
107
|
-
}
|
|
108
|
-
async function getFileContentAtCommit({ owner, repo, authToken, rootDir }, file, ref) {
|
|
109
|
-
const result = await graphQL(
|
|
110
|
-
`query GetFileContent($owner: String!, $repo: String!, $expression: String!) {
|
|
134
|
+
}
|
|
135
|
+
return allRevisions.sort((a, b) => b.createdAt - a.createdAt);
|
|
136
|
+
}
|
|
137
|
+
async #getFileContentAtCommit(file, ref) {
|
|
138
|
+
const { owner, repo, authToken, rootDir } = this.#options;
|
|
139
|
+
const result = await this.#graphQL(
|
|
140
|
+
`query GetFileContent($owner: String!, $repo: String!, $expression: String!) {
|
|
111
141
|
repository(owner: $owner, name: $repo) {
|
|
112
142
|
object(expression: $expression) {
|
|
113
143
|
... on Blob {
|
|
@@ -116,97 +146,94 @@ async function getFileContentAtCommit({ owner, repo, authToken, rootDir }, file,
|
|
|
116
146
|
}
|
|
117
147
|
}
|
|
118
148
|
}`,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
async
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
149
|
+
{ owner, repo, expression: `${ref}:${join(rootDir, file)}` },
|
|
150
|
+
authToken
|
|
151
|
+
);
|
|
152
|
+
return result.data.repository.object?.text;
|
|
153
|
+
}
|
|
154
|
+
async #applyChangesToRepo(expectedHeadOid, changes, commitMessage) {
|
|
155
|
+
const { additions, deletions } = await this.#processChanges(changes);
|
|
156
|
+
const { owner, repo, branch, authToken } = this.#options;
|
|
157
|
+
return this.#graphQL(
|
|
158
|
+
`mutation CreateCommitOnBranch($input: CreateCommitOnBranchInput!) {
|
|
129
159
|
createCommitOnBranch(input: $input) {
|
|
130
160
|
commit {
|
|
131
161
|
oid
|
|
132
162
|
}
|
|
133
163
|
}
|
|
134
164
|
}`,
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
throw error;
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
async function processChanges({ rootDir, contentDir }, changes) {
|
|
169
|
-
const additions = Array();
|
|
170
|
-
const deletions = Array();
|
|
171
|
-
for (const change of changes) {
|
|
172
|
-
switch (change.op) {
|
|
173
|
-
case "addContent": {
|
|
174
|
-
additions.push({
|
|
175
|
-
path: join(contentDir, change.path),
|
|
176
|
-
contents: btoa(change.contents)
|
|
177
|
-
});
|
|
178
|
-
break;
|
|
179
|
-
}
|
|
180
|
-
case "uploadFile": {
|
|
181
|
-
const file = join(rootDir, change.location);
|
|
182
|
-
additions.push({
|
|
183
|
-
path: file,
|
|
184
|
-
contents: await fetchUploadedContent(change.url)
|
|
185
|
-
});
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
case "deleteContent": {
|
|
189
|
-
const file = join(contentDir, change.path);
|
|
190
|
-
deletions.push({ path: file });
|
|
191
|
-
break;
|
|
165
|
+
{
|
|
166
|
+
input: {
|
|
167
|
+
branch: {
|
|
168
|
+
repositoryNameWithOwner: `${owner}/${repo}`,
|
|
169
|
+
branchName: branch
|
|
170
|
+
},
|
|
171
|
+
message: { headline: commitMessage },
|
|
172
|
+
fileChanges: { additions, deletions },
|
|
173
|
+
expectedHeadOid
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
authToken
|
|
177
|
+
).then((result) => {
|
|
178
|
+
const commitId = result.data.createCommitOnBranch.commit.oid;
|
|
179
|
+
return commitId;
|
|
180
|
+
}).catch((error) => {
|
|
181
|
+
if (error instanceof Error) {
|
|
182
|
+
const mismatchMessage = /is at ([a-z0-9]+) but expected ([a-z0-9]+)/;
|
|
183
|
+
const match = error.message.match(mismatchMessage);
|
|
184
|
+
if (match) {
|
|
185
|
+
const [_, actual, expected] = match;
|
|
186
|
+
throw new ShaMismatchError(actual, expected);
|
|
187
|
+
}
|
|
188
|
+
const expectedMessage = /Expected branch to point to "([a-z0-9]+)"/;
|
|
189
|
+
const expectedMatch = error.message.match(expectedMessage);
|
|
190
|
+
if (expectedMatch) {
|
|
191
|
+
const actualSha = expectedMatch[1];
|
|
192
|
+
throw new ShaMismatchError(actualSha, expectedHeadOid);
|
|
193
|
+
}
|
|
192
194
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
throw error;
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async #processChanges(changes) {
|
|
199
|
+
const { rootDir } = this.#options;
|
|
200
|
+
const additions = Array();
|
|
201
|
+
const deletions = Array();
|
|
202
|
+
for (const change of changes) {
|
|
203
|
+
switch (change.op) {
|
|
204
|
+
case "addContent": {
|
|
205
|
+
additions.push({
|
|
206
|
+
path: join(this.contentLocation, change.path),
|
|
207
|
+
contents: btoa(change.contents)
|
|
208
|
+
});
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case "uploadFile": {
|
|
212
|
+
const file = join(rootDir, change.location);
|
|
213
|
+
additions.push({
|
|
214
|
+
path: file,
|
|
215
|
+
contents: await this.#fetchUploadedContent(change.url)
|
|
216
|
+
});
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
case "deleteContent": {
|
|
220
|
+
const file = join(this.contentLocation, change.path);
|
|
221
|
+
deletions.push({ path: file });
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
case "removeFile": {
|
|
225
|
+
const file = join(rootDir, change.location);
|
|
226
|
+
deletions.push({ path: file });
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
197
229
|
}
|
|
198
230
|
}
|
|
231
|
+
return { additions, deletions };
|
|
199
232
|
}
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
repo,
|
|
205
|
-
branch,
|
|
206
|
-
authToken
|
|
207
|
-
}) {
|
|
208
|
-
return graphQL(
|
|
209
|
-
`query GetLatestCommit($owner: String!, $repo: String!, $branch: String!) {
|
|
233
|
+
async #getLatestCommitOid() {
|
|
234
|
+
const { owner, repo, branch, authToken } = this.#options;
|
|
235
|
+
return this.#graphQL(
|
|
236
|
+
`query GetLatestCommit($owner: String!, $repo: String!, $branch: String!) {
|
|
210
237
|
repository(owner: $owner, name: $repo) {
|
|
211
238
|
ref(qualifiedName: $branch) {
|
|
212
239
|
target {
|
|
@@ -215,14 +242,15 @@ async function getLatestCommitOid({
|
|
|
215
242
|
}
|
|
216
243
|
}
|
|
217
244
|
}`,
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
async
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
245
|
+
{ owner, repo, branch },
|
|
246
|
+
authToken
|
|
247
|
+
).then((result) => result.data.repository.ref.target.oid);
|
|
248
|
+
}
|
|
249
|
+
async #fetchUploadedContent(url) {
|
|
250
|
+
const response = await fetch(url);
|
|
251
|
+
return base64.stringify(new Uint8Array(await response.arrayBuffer()));
|
|
252
|
+
}
|
|
253
|
+
};
|
|
226
254
|
export {
|
|
227
255
|
GithubApi
|
|
228
256
|
};
|
package/dist/cli/Serve.js
CHANGED
package/dist/cli/bin.js
CHANGED
|
@@ -3,6 +3,8 @@ import "../../chunks/chunk-NZLE2WMY.js";
|
|
|
3
3
|
// src/cli/serve/GitHistory.ts
|
|
4
4
|
import { JsonLoader } from "alinea/backend/loader/JsonLoader";
|
|
5
5
|
import { execGit } from "alinea/backend/util/ExecGit";
|
|
6
|
+
import { fileVersions } from "alinea/core/util/EntryFilenames";
|
|
7
|
+
import { parseCoAuthoredBy } from "../util/CommitMessage.js";
|
|
6
8
|
var encoder = new TextEncoder();
|
|
7
9
|
var GitHistory = class {
|
|
8
10
|
constructor(config, rootDir) {
|
|
@@ -10,34 +12,34 @@ var GitHistory = class {
|
|
|
10
12
|
this.rootDir = rootDir;
|
|
11
13
|
}
|
|
12
14
|
async revisions(file) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
user
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
return
|
|
15
|
+
const versions = fileVersions(file);
|
|
16
|
+
const results = Array();
|
|
17
|
+
for (const versioned of versions) {
|
|
18
|
+
const output = await execGit(this.rootDir, [
|
|
19
|
+
"log",
|
|
20
|
+
"--follow",
|
|
21
|
+
"--name-status",
|
|
22
|
+
"--pretty=format:%H%n%at%n%s%n%ae%n%an%n%f",
|
|
23
|
+
"--",
|
|
24
|
+
versioned
|
|
25
|
+
]);
|
|
26
|
+
const revisions = output.split("\n\n").filter((entry) => {
|
|
27
|
+
return entry.includes("\n");
|
|
28
|
+
}).map((entry) => {
|
|
29
|
+
const [ref, timestamp, message, email, name, changedFile, ...rest] = entry.split("\n");
|
|
30
|
+
const fileLocation = rest.length ? rest[rest.length - 1].split(" ").pop().trim() : versioned;
|
|
31
|
+
const user = parseCoAuthoredBy(message) ?? { name, email };
|
|
32
|
+
return {
|
|
33
|
+
ref,
|
|
34
|
+
createdAt: Number.parseInt(timestamp) * 1e3,
|
|
35
|
+
description: message,
|
|
36
|
+
file: fileLocation,
|
|
37
|
+
user
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
results.push(...revisions);
|
|
41
|
+
}
|
|
42
|
+
return results;
|
|
41
43
|
}
|
|
42
44
|
async revisionData(file, ref) {
|
|
43
45
|
const { config } = this;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import "../../chunks/chunk-NZLE2WMY.js";
|
|
2
|
+
|
|
3
|
+
// src/cli/util/CommitMessage.ts
|
|
4
|
+
function parseCoAuthoredBy(commitMessage) {
|
|
5
|
+
const regex = /Co-authored-by:\s*(.+?)\s*<(\S+@\S+\.\S+)>/;
|
|
6
|
+
const match = commitMessage.match(regex);
|
|
7
|
+
if (match && match.length >= 3) {
|
|
8
|
+
const name = match[1].trim();
|
|
9
|
+
const email = match[2].trim();
|
|
10
|
+
return { name, email };
|
|
11
|
+
}
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
parseCoAuthoredBy
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -273,20 +273,23 @@ var EntryTransaction = class {
|
|
|
273
273
|
this.#tx.remove(entry.filePath);
|
|
274
274
|
const record = createRecord({ ...entry, path }, "published");
|
|
275
275
|
const contents = new TextEncoder().encode(JSON.stringify(record, null, 2));
|
|
276
|
-
this.#tx.add(`${childrenDir}.json`, contents);
|
|
277
276
|
if (pathChange) {
|
|
278
277
|
this.#tx.remove(`${entry.parentDir}/${entry.path}.json`);
|
|
279
278
|
this.#tx.rename(entry.childrenDir, childrenDir);
|
|
280
279
|
}
|
|
280
|
+
this.#tx.add(`${childrenDir}.json`, contents);
|
|
281
281
|
this.#messages.push(this.#reportOp("publish", entry.title));
|
|
282
282
|
return this;
|
|
283
283
|
}
|
|
284
284
|
unpublish({ id, locale }) {
|
|
285
285
|
const index = this.#index;
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
});
|
|
286
|
+
const versions = index.byId.get(id)?.locales.get(locale);
|
|
287
|
+
const entry = versions?.main;
|
|
289
288
|
assert(entry, `Entry not found: ${id}`);
|
|
289
|
+
for (const version of versions.values()) {
|
|
290
|
+
if (version.main) continue;
|
|
291
|
+
this.#tx.remove(version.filePath);
|
|
292
|
+
}
|
|
290
293
|
this.#checks.push([entry.filePath, entry.fileHash]);
|
|
291
294
|
this.#tx.rename(entry.filePath, `${entry.childrenDir}.draft.json`);
|
|
292
295
|
this.#messages.push(this.#reportOp("unpublish", entry.title));
|
|
@@ -294,10 +297,13 @@ var EntryTransaction = class {
|
|
|
294
297
|
}
|
|
295
298
|
archive({ id, locale }) {
|
|
296
299
|
const index = this.#index;
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
});
|
|
300
|
+
const versions = index.byId.get(id)?.locales.get(locale);
|
|
301
|
+
const entry = versions?.main;
|
|
300
302
|
assert(entry, `Entry not found: ${id}`);
|
|
303
|
+
for (const version of versions.values()) {
|
|
304
|
+
if (version.main) continue;
|
|
305
|
+
this.#tx.remove(version.filePath);
|
|
306
|
+
}
|
|
301
307
|
this.#checks.push([entry.filePath, entry.fileHash]);
|
|
302
308
|
this.#tx.rename(entry.filePath, `${entry.childrenDir}.archived.json`);
|
|
303
309
|
this.#messages.push(this.#reportOp("archive", entry.title));
|
|
@@ -6,11 +6,13 @@ export interface GithubSourceOptions {
|
|
|
6
6
|
owner: string;
|
|
7
7
|
repo: string;
|
|
8
8
|
branch: string;
|
|
9
|
+
rootDir: string;
|
|
9
10
|
contentDir: string;
|
|
10
11
|
}
|
|
11
12
|
export declare class GithubSource implements Source {
|
|
12
13
|
#private;
|
|
13
14
|
constructor(options: GithubSourceOptions);
|
|
15
|
+
protected get contentLocation(): string;
|
|
14
16
|
getTree(): Promise<ReadonlyTree>;
|
|
15
17
|
shaAt(ref: string): Promise<string>;
|
|
16
18
|
getTreeIfDifferent(sha: string): Promise<ReadonlyTree | undefined>;
|
|
@@ -14,6 +14,12 @@ var GithubSource = class {
|
|
|
14
14
|
constructor(options) {
|
|
15
15
|
this.#options = options;
|
|
16
16
|
}
|
|
17
|
+
get contentLocation() {
|
|
18
|
+
const { contentDir, rootDir } = this.#options;
|
|
19
|
+
if (contentDir.startsWith("/")) return contentDir.slice(1);
|
|
20
|
+
if (rootDir.endsWith("/")) return rootDir + contentDir;
|
|
21
|
+
return `${rootDir}/${contentDir}`;
|
|
22
|
+
}
|
|
17
23
|
async getTree() {
|
|
18
24
|
const current = this.#current;
|
|
19
25
|
const newTree = await this.getTreeIfDifferent(current.sha);
|
|
@@ -21,8 +27,8 @@ var GithubSource = class {
|
|
|
21
27
|
return current;
|
|
22
28
|
}
|
|
23
29
|
async shaAt(ref) {
|
|
24
|
-
const {
|
|
25
|
-
const parentDir =
|
|
30
|
+
const { owner, repo, authToken } = this.#options;
|
|
31
|
+
const parentDir = this.contentLocation.split("/").slice(0, -1).join("/");
|
|
26
32
|
const parentInfo = await fetch(
|
|
27
33
|
`https://api.github.com/repos/${owner}/${repo}/contents/${parentDir}?ref=${ref}`,
|
|
28
34
|
{ headers: { Authorization: `Bearer ${authToken}` } }
|
|
@@ -30,7 +36,7 @@ var GithubSource = class {
|
|
|
30
36
|
assert(parentInfo.ok, `Failed to get parent: ${parentInfo.statusText}`);
|
|
31
37
|
const parents = await parentInfo.json();
|
|
32
38
|
assert(Array.isArray(parents));
|
|
33
|
-
const parent = parents.find((entry) => entry.path ===
|
|
39
|
+
const parent = parents.find((entry) => entry.path === this.contentLocation);
|
|
34
40
|
if (!parent) return ReadonlyTree.EMPTY.sha;
|
|
35
41
|
assert(typeof parent.sha === "string");
|
|
36
42
|
return parent.sha;
|
package/dist/core/source/Tree.js
CHANGED
|
@@ -85,7 +85,8 @@ var TreeBase = class _TreeBase {
|
|
|
85
85
|
}
|
|
86
86
|
equals(other) {
|
|
87
87
|
if (other instanceof ReadonlyTree) return this.sha === other.sha;
|
|
88
|
-
|
|
88
|
+
const canCompare = this.sha && other.sha;
|
|
89
|
+
if (canCompare && this.sha === other.sha) return true;
|
|
89
90
|
if (this.nodes.size !== other.nodes.size) return false;
|
|
90
91
|
for (const [name, entry] of this.nodes) {
|
|
91
92
|
const otherEntry = other.nodes.get(name);
|
|
@@ -29,3 +29,4 @@ export declare function entryFile(config: Config, entry: EntryRow): string;
|
|
|
29
29
|
export declare function entryUrl(type: Type, meta: EntryUrlMeta): string;
|
|
30
30
|
export declare function pathSuffix(path: string, conflictingPaths: Array<string>): number | undefined;
|
|
31
31
|
export declare function applySuffix(path: string, suffix: number): string;
|
|
32
|
+
export declare function fileVersions(file: string): string[];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "../../chunks/chunk-NZLE2WMY.js";
|
|
2
2
|
|
|
3
3
|
// src/core/util/EntryFilenames.ts
|
|
4
|
+
import * as paths from "alinea/core/util/Paths";
|
|
4
5
|
import { entryStatuses } from "../Entry.js";
|
|
5
6
|
import { ALT_STATUS } from "../EntryRow.js";
|
|
6
7
|
import { getRoot, getType } from "../Internal.js";
|
|
@@ -74,6 +75,16 @@ function pathSuffix(path, conflictingPaths) {
|
|
|
74
75
|
function applySuffix(path, suffix) {
|
|
75
76
|
return `${path}-${suffix}`;
|
|
76
77
|
}
|
|
78
|
+
function fileVersions(file) {
|
|
79
|
+
const dir = paths.dirname(file);
|
|
80
|
+
const base = paths.basename(file, ".json");
|
|
81
|
+
const [name] = entryInfo(base);
|
|
82
|
+
return [
|
|
83
|
+
`${dir}/${name}.json`,
|
|
84
|
+
`${dir}/${name}.draft.json`,
|
|
85
|
+
`${dir}/${name}.archived.json`
|
|
86
|
+
];
|
|
87
|
+
}
|
|
77
88
|
export {
|
|
78
89
|
applySuffix,
|
|
79
90
|
entryChildrenDir,
|
|
@@ -82,6 +93,7 @@ export {
|
|
|
82
93
|
entryFilepath,
|
|
83
94
|
entryInfo,
|
|
84
95
|
entryUrl,
|
|
96
|
+
fileVersions,
|
|
85
97
|
pathSuffix,
|
|
86
98
|
workspaceMediaDir
|
|
87
99
|
};
|
|
@@ -38,7 +38,7 @@ export declare const entryRoute: Route<{
|
|
|
38
38
|
unPublish: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
39
39
|
init: null;
|
|
40
40
|
};
|
|
41
|
-
|
|
41
|
+
archive: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
42
42
|
init: null;
|
|
43
43
|
};
|
|
44
44
|
publishArchived: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
@@ -50,7 +50,7 @@ export declare const entryRoute: Route<{
|
|
|
50
50
|
deleteMediaLibrary: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
51
51
|
init: null;
|
|
52
52
|
};
|
|
53
|
-
|
|
53
|
+
deleteEntry: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
54
54
|
init: null;
|
|
55
55
|
};
|
|
56
56
|
saveTranslation: import("jotai").WritableAtom<null, [locale: string], Promise<void>> & {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
atomFamily
|
|
3
|
-
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
4
1
|
import {
|
|
5
2
|
useAtomValue
|
|
6
3
|
} from "../../chunks/chunk-TOJF2G3X.js";
|
|
4
|
+
import {
|
|
5
|
+
atomFamily
|
|
6
|
+
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
7
7
|
import {
|
|
8
8
|
atom
|
|
9
9
|
} from "../../chunks/chunk-WJ67RR7S.js";
|
|
@@ -28,7 +28,7 @@ export declare enum EntryTransition {
|
|
|
28
28
|
ArchivePublished = 7,
|
|
29
29
|
PublishArchived = 8,
|
|
30
30
|
DeleteFile = 9,
|
|
31
|
-
|
|
31
|
+
DeleteEntry = 10
|
|
32
32
|
}
|
|
33
33
|
export declare const entryEditorAtoms: import("jotai/vanilla/utils/atomFamily.js").AtomFamily<EntryEditorParams, import("jotai").Atom<Promise<{
|
|
34
34
|
transition: import("jotai").PrimitiveAtom<EntryTransition | undefined> & {
|
|
@@ -68,7 +68,7 @@ export declare const entryEditorAtoms: import("jotai/vanilla/utils/atomFamily.js
|
|
|
68
68
|
unPublish: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
69
69
|
init: null;
|
|
70
70
|
};
|
|
71
|
-
|
|
71
|
+
archive: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
72
72
|
init: null;
|
|
73
73
|
};
|
|
74
74
|
publishArchived: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
@@ -80,7 +80,7 @@ export declare const entryEditorAtoms: import("jotai/vanilla/utils/atomFamily.js
|
|
|
80
80
|
deleteMediaLibrary: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
81
81
|
init: null;
|
|
82
82
|
};
|
|
83
|
-
|
|
83
|
+
deleteEntry: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
84
84
|
init: null;
|
|
85
85
|
};
|
|
86
86
|
saveTranslation: import("jotai").WritableAtom<null, [locale: string], Promise<void>> & {
|
|
@@ -190,7 +190,7 @@ export declare function createEntryEditor(entryData: EntryData): {
|
|
|
190
190
|
unPublish: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
191
191
|
init: null;
|
|
192
192
|
};
|
|
193
|
-
|
|
193
|
+
archive: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
194
194
|
init: null;
|
|
195
195
|
};
|
|
196
196
|
publishArchived: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
@@ -202,7 +202,7 @@ export declare function createEntryEditor(entryData: EntryData): {
|
|
|
202
202
|
deleteMediaLibrary: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
203
203
|
init: null;
|
|
204
204
|
};
|
|
205
|
-
|
|
205
|
+
deleteEntry: import("jotai").WritableAtom<null, [], Promise<void>> & {
|
|
206
206
|
init: null;
|
|
207
207
|
};
|
|
208
208
|
saveTranslation: import("jotai").WritableAtom<null, [locale: string], Promise<void>> & {
|
|
@@ -51,7 +51,7 @@ var EntryTransition = /* @__PURE__ */ ((EntryTransition2) => {
|
|
|
51
51
|
EntryTransition2[EntryTransition2["ArchivePublished"] = 7] = "ArchivePublished";
|
|
52
52
|
EntryTransition2[EntryTransition2["PublishArchived"] = 8] = "PublishArchived";
|
|
53
53
|
EntryTransition2[EntryTransition2["DeleteFile"] = 9] = "DeleteFile";
|
|
54
|
-
EntryTransition2[EntryTransition2["
|
|
54
|
+
EntryTransition2[EntryTransition2["DeleteEntry"] = 10] = "DeleteEntry";
|
|
55
55
|
return EntryTransition2;
|
|
56
56
|
})(EntryTransition || {});
|
|
57
57
|
var entryTransitionAtoms = atomFamily((id) => {
|
|
@@ -396,7 +396,7 @@ function createEntryEditor(entryData) {
|
|
|
396
396
|
errorMessage: "Could not complete unpublish action, please try again later"
|
|
397
397
|
});
|
|
398
398
|
});
|
|
399
|
-
const
|
|
399
|
+
const archive = atom(null, async (get, set) => {
|
|
400
400
|
const db = get(dbAtom);
|
|
401
401
|
return set(action, {
|
|
402
402
|
transition: 7 /* ArchivePublished */,
|
|
@@ -426,7 +426,7 @@ function createEntryEditor(entryData) {
|
|
|
426
426
|
if (!result) return;
|
|
427
427
|
const db = get(dbAtom);
|
|
428
428
|
return set(action, {
|
|
429
|
-
transition: 10 /*
|
|
429
|
+
transition: 10 /* DeleteEntry */,
|
|
430
430
|
result: db.remove(activeVersion.id),
|
|
431
431
|
errorMessage: "Could not complete delete action, please try again later"
|
|
432
432
|
});
|
|
@@ -441,10 +441,10 @@ function createEntryEditor(entryData) {
|
|
|
441
441
|
errorMessage: "Could not complete delete action, please try again later"
|
|
442
442
|
});
|
|
443
443
|
});
|
|
444
|
-
const
|
|
444
|
+
const deleteEntry = atom(null, async (get, set) => {
|
|
445
445
|
const db = get(dbAtom);
|
|
446
446
|
return set(action, {
|
|
447
|
-
transition: 10 /*
|
|
447
|
+
transition: 10 /* DeleteEntry */,
|
|
448
448
|
result: db.remove(activeVersion.id),
|
|
449
449
|
errorMessage: "Could not complete delete action, please try again later"
|
|
450
450
|
});
|
|
@@ -581,11 +581,11 @@ function createEntryEditor(entryData) {
|
|
|
581
581
|
publishDraft,
|
|
582
582
|
discardDraft,
|
|
583
583
|
unPublish,
|
|
584
|
-
|
|
584
|
+
archive,
|
|
585
585
|
publishArchived,
|
|
586
586
|
deleteFile,
|
|
587
587
|
deleteMediaLibrary,
|
|
588
|
-
|
|
588
|
+
deleteEntry,
|
|
589
589
|
saveTranslation,
|
|
590
590
|
discardEdits,
|
|
591
591
|
showHistory,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
atomFamily
|
|
3
|
-
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
4
1
|
import {
|
|
5
2
|
require_dataloader
|
|
6
3
|
} from "../../chunks/chunk-3TNMMA3W.js";
|
|
4
|
+
import {
|
|
5
|
+
atomFamily
|
|
6
|
+
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
7
7
|
import {
|
|
8
8
|
atom
|
|
9
9
|
} from "../../chunks/chunk-WJ67RR7S.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
atomFamily
|
|
3
|
-
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
4
1
|
import {
|
|
5
2
|
useAtom,
|
|
6
3
|
useAtomValue,
|
|
7
4
|
useSetAtom
|
|
8
5
|
} from "../../chunks/chunk-TOJF2G3X.js";
|
|
6
|
+
import {
|
|
7
|
+
atomFamily
|
|
8
|
+
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
9
9
|
import {
|
|
10
10
|
atom
|
|
11
11
|
} from "../../chunks/chunk-WJ67RR7S.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
atomWithStorage
|
|
3
|
-
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
4
1
|
import {
|
|
5
2
|
useAtom
|
|
6
3
|
} from "../../chunks/chunk-TOJF2G3X.js";
|
|
4
|
+
import {
|
|
5
|
+
atomWithStorage
|
|
6
|
+
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
7
7
|
import {
|
|
8
8
|
atom
|
|
9
9
|
} from "../../chunks/chunk-WJ67RR7S.js";
|
|
@@ -113,7 +113,7 @@ var transitions = {
|
|
|
113
113
|
[EntryTransition.ArchivePublished]: "Archiving",
|
|
114
114
|
[EntryTransition.PublishArchived]: "Publishing",
|
|
115
115
|
[EntryTransition.DeleteFile]: "Deleting",
|
|
116
|
-
[EntryTransition.
|
|
116
|
+
[EntryTransition.DeleteEntry]: "Deleting"
|
|
117
117
|
};
|
|
118
118
|
var variantIcon = {
|
|
119
119
|
draft: IcRoundEdit,
|
|
@@ -144,9 +144,9 @@ function EntryHeader({ editor, editable = true }) {
|
|
|
144
144
|
const restoreRevision = useSetAtom(editor.restoreRevision);
|
|
145
145
|
const discardDraft = useSetAtom(editor.discardDraft);
|
|
146
146
|
const unPublish = useSetAtom(editor.unPublish);
|
|
147
|
-
const
|
|
147
|
+
const archive = useSetAtom(editor.archive);
|
|
148
148
|
const publishArchived = useSetAtom(editor.publishArchived);
|
|
149
|
-
const
|
|
149
|
+
const deleteEntry = useSetAtom(editor.deleteEntry);
|
|
150
150
|
const deleteFile = useSetAtom(editor.deleteFile);
|
|
151
151
|
const deleteMediaLibrary = useSetAtom(editor.deleteMediaLibrary);
|
|
152
152
|
const queryClient = useQueryClient();
|
|
@@ -191,6 +191,7 @@ function EntryHeader({ editor, editable = true }) {
|
|
|
191
191
|
};
|
|
192
192
|
input.click();
|
|
193
193
|
}
|
|
194
|
+
const isParentUnpublished = editor.parents.some((p) => p.status === "draft");
|
|
194
195
|
const options = variant === "draft" ? /* @__PURE__ */ jsx(
|
|
195
196
|
DropdownMenu.Item,
|
|
196
197
|
{
|
|
@@ -231,14 +232,7 @@ function EntryHeader({ editor, editable = true }) {
|
|
|
231
232
|
children: "Unpublish"
|
|
232
233
|
}
|
|
233
234
|
),
|
|
234
|
-
/* @__PURE__ */ jsx(
|
|
235
|
-
DropdownMenu.Item,
|
|
236
|
-
{
|
|
237
|
-
className: styles.root.action(),
|
|
238
|
-
onClick: archivePublished,
|
|
239
|
-
children: "Archive"
|
|
240
|
-
}
|
|
241
|
-
)
|
|
235
|
+
/* @__PURE__ */ jsx(DropdownMenu.Item, { className: styles.root.action(), onClick: archive, children: "Archive" })
|
|
242
236
|
] }) : variant === "archived" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
243
237
|
canPublish && /* @__PURE__ */ jsx(
|
|
244
238
|
DropdownMenu.Item,
|
|
@@ -252,11 +246,18 @@ function EntryHeader({ editor, editable = true }) {
|
|
|
252
246
|
DropdownMenu.Item,
|
|
253
247
|
{
|
|
254
248
|
className: styles.root.action(),
|
|
255
|
-
onClick:
|
|
249
|
+
onClick: deleteEntry,
|
|
256
250
|
children: "Delete"
|
|
257
251
|
}
|
|
258
252
|
)
|
|
259
|
-
] }) :
|
|
253
|
+
] }) : variant === "unpublished" ? isParentUnpublished ? /* @__PURE__ */ jsx(
|
|
254
|
+
DropdownMenu.Item,
|
|
255
|
+
{
|
|
256
|
+
className: styles.root.action(),
|
|
257
|
+
onClick: deleteEntry,
|
|
258
|
+
children: "Delete"
|
|
259
|
+
}
|
|
260
|
+
) : /* @__PURE__ */ jsx(DropdownMenu.Item, { className: styles.root.action(), onClick: archive, children: "Archive" }) : null;
|
|
260
261
|
const inTransition = currentTransition !== void 0;
|
|
261
262
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
262
263
|
isReplacing && /* @__PURE__ */ jsx(FileUploader, {}),
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
unwrap
|
|
3
|
-
} from "../../../chunks/chunk-WDCPVJJC.js";
|
|
4
1
|
import {
|
|
5
2
|
useAtomValue
|
|
6
3
|
} from "../../../chunks/chunk-TOJF2G3X.js";
|
|
4
|
+
import {
|
|
5
|
+
unwrap
|
|
6
|
+
} from "../../../chunks/chunk-WDCPVJJC.js";
|
|
7
7
|
import "../../../chunks/chunk-WJ67RR7S.js";
|
|
8
8
|
import "../../../chunks/chunk-NZLE2WMY.js";
|
|
9
9
|
|
|
@@ -18,12 +18,12 @@ import {
|
|
|
18
18
|
import {
|
|
19
19
|
dist_default
|
|
20
20
|
} from "../../chunks/chunk-A5O3N2GS.js";
|
|
21
|
-
import {
|
|
22
|
-
atomWithStorage
|
|
23
|
-
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
24
21
|
import {
|
|
25
22
|
useAtom
|
|
26
23
|
} from "../../chunks/chunk-TOJF2G3X.js";
|
|
24
|
+
import {
|
|
25
|
+
atomWithStorage
|
|
26
|
+
} from "../../chunks/chunk-WDCPVJJC.js";
|
|
27
27
|
import "../../chunks/chunk-WJ67RR7S.js";
|
|
28
28
|
import "../../chunks/chunk-NZLE2WMY.js";
|
|
29
29
|
|