Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/publish/common/data.ts
6446 views
1
/*
2
* data.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*/
6
7
import { ensureDirSync, existsSync } from "../../deno_ral/fs.ts";
8
import { join } from "../../deno_ral/path.ts";
9
10
import { quartoDataDir } from "../../core/appdirs.ts";
11
import { normalizePath } from "../../core/path.ts";
12
import { ProjectContext } from "../../project/types.ts";
13
import { AccountToken, PublishProvider } from "../provider-types.ts";
14
import { PublishRecord } from "../types.ts";
15
16
export function publishDataDir() {
17
return quartoDataDir("publish");
18
}
19
20
export function publishRecordsPath() {
21
return join(publishDataDir(), "records.json");
22
}
23
24
export function accountsDataDir() {
25
const accountsDir = join(publishDataDir(), "accounts");
26
ensureDirSync(accountsDir);
27
return accountsDir;
28
}
29
30
export async function readAccountsPublishedTo(
31
input: string | ProjectContext,
32
provider: PublishProvider,
33
record: PublishRecord,
34
): Promise<AccountToken[]> {
35
const source = normalizePath(
36
typeof input === "string" ? input : input.dir,
37
);
38
const tokens: AccountToken[] = [];
39
const publishRecordsFile = publishRecordsPath();
40
if (existsSync(publishRecordsFile)) {
41
const records = JSON.parse(
42
Deno.readTextFileSync(publishRecordsFile),
43
) as PublishRecords;
44
if (records[source] && records[source][provider.name]) {
45
// see if we can associate registered accounts w/ the publish target accounts
46
const publishIdentifiers = records[source][provider.name];
47
const accounts = await provider.accountTokens();
48
for (const publishIdentifier of publishIdentifiers) {
49
const account = accounts.find((account) =>
50
publishIdentifier === publishRecordIdentifier(record, account)
51
);
52
if (account) {
53
tokens.push(account);
54
}
55
}
56
}
57
}
58
return tokens;
59
}
60
61
export function writePublishRecord(
62
source: string,
63
provider: string,
64
account: AccountToken,
65
record: PublishRecord,
66
) {
67
// resolve to real path
68
source = normalizePath(source);
69
70
// write a record of which account was was used to publish
71
// in a sidecar list so that we can pair it for republish
72
const publishRecordsFile = publishRecordsPath();
73
const publishRecords =
74
(existsSync(publishRecordsFile)
75
? JSON.parse(Deno.readTextFileSync(publishRecordsFile))
76
: {}) as PublishRecords;
77
if (!publishRecords[source]) {
78
publishRecords[source] = {
79
[provider]: [],
80
};
81
}
82
if (!publishRecords[source][provider]) {
83
publishRecords[source][provider] = [];
84
}
85
const publishedTo = publishRecordIdentifier(record, account);
86
if (!publishRecords[source][provider].includes(publishedTo)) {
87
publishRecords[source][provider].push(publishedTo);
88
}
89
Deno.writeTextFileSync(
90
publishRecordsFile,
91
JSON.stringify(publishRecords, undefined, 2),
92
);
93
}
94
95
type PublishRecords = Record<string, Record<string, string[]>>;
96
97
export function publishRecordIdentifier(
98
record: PublishRecord,
99
account?: AccountToken,
100
) {
101
return `${record.id}/${account?.server ? account.server + "/" : ""}${
102
account
103
?.name || ""
104
}`;
105
}
106
107