@revos/cli 0.1.0 → 0.1.1
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/bin/revos.js +1 -1
- package/dist/adapters/oclif/commands/auth/login.mjs +2 -2
- package/dist/adapters/oclif/commands/auth/logout.mjs +2 -2
- package/dist/adapters/oclif/commands/auth/status.mjs +2 -2
- package/dist/adapters/oclif/commands/init.mjs +5 -4
- package/dist/adapters/oclif/commands/org/current.mjs +3 -3
- package/dist/adapters/oclif/commands/org/list.mjs +3 -3
- package/dist/adapters/oclif/commands/org/switch.mjs +3 -3
- package/dist/adapters/oclif/commands/overlays/diff.mjs +3 -3
- package/dist/adapters/oclif/commands/overlays/pull.mjs +3 -3
- package/dist/adapters/oclif/commands/overlays/push.mjs +3 -3
- package/dist/adapters/oclif/commands/overlays/status.mjs +3 -3
- package/dist/{base.command-BGM225ik.mjs → base.command-DlYMawJ6.mjs} +1 -1
- package/dist/{core-Bif-kxlo.mjs → core-Dq15hO6f.mjs} +70 -208
- package/dist/{index-C0e8MXGP.d.mts → index-DuqD2b_7.d.mts} +2 -8
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/templates/.devcontainer/Dockerfile +14 -0
- package/dist/templates/.devcontainer/devcontainer.json +54 -0
- package/dist/templates/.devcontainer/setup.sh +32 -0
- package/dist/templates/AGENTS.md +2 -3
- package/dist/templates/CLAUDE.md +0 -16
- package/dist/templates/README.md +23 -0
- package/dist/templates/dbt/dbt_project.yml +22 -0
- package/dist/templates/index.ts +4 -0
- package/dist/templates/skills/create-semantic-model/SKILL.md +1611 -0
- package/dist/templates/skills/explore-lakehouse/SKILL.md +131 -0
- package/package.json +1 -3
package/bin/revos.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as getCredentialsPath, C as getUserInfo, D as tokenResponseToCredentials, N as saveCredentials, O as startOAuthServer, S as generatePKCEChallenge, T as setClerkConfig, b as buildAuthorizationUrl, m as unwrap, n as selectOrganization, p as createApiClient, x as exchangeCodeForTokens } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { A as getCredentialsPath, C as getUserInfo, D as tokenResponseToCredentials, N as saveCredentials, O as startOAuthServer, S as generatePKCEChallenge, T as setClerkConfig, b as buildAuthorizationUrl, m as unwrap, n as selectOrganization, p as createApiClient, x as exchangeCodeForTokens } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Flags } from "@oclif/core";
|
|
5
5
|
import open from "open";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { k as deleteCredentials } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { k as deleteCredentials } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
//#region src/adapters/oclif/commands/auth/logout.ts
|
|
4
4
|
var AuthLogout = class extends BaseCommand {
|
|
5
5
|
static description = "Remove stored authentication credentials";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as getCredentialsPath, M as loadCredentials, j as isTokenExpired } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { A as getCredentialsPath, M as loadCredentials, j as isTokenExpired } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
//#region src/adapters/oclif/commands/auth/status.ts
|
|
5
5
|
var AuthStatus = class extends BaseCommand {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { P as ApiError, t as InitService, y as getConfig } from "../../../core-
|
|
1
|
+
import { P as ApiError, t as InitService, y as getConfig } from "../../../core-Dq15hO6f.mjs";
|
|
2
2
|
import { TEMPLATES_DIR } from "../../../templates/index.mjs";
|
|
3
|
-
import { t as BaseCommand } from "../../../base.command-
|
|
3
|
+
import { t as BaseCommand } from "../../../base.command-DlYMawJ6.mjs";
|
|
4
4
|
import * as path from "path";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import { Args } from "@oclif/core";
|
|
@@ -12,7 +12,7 @@ var Init = class extends BaseCommand {
|
|
|
12
12
|
required: false
|
|
13
13
|
}) };
|
|
14
14
|
async run() {
|
|
15
|
-
const { apiUrl, token } = getConfig();
|
|
15
|
+
const { apiUrl, token, organizationId } = await getConfig();
|
|
16
16
|
const projectName = this.args.name ?? path.basename(process.cwd());
|
|
17
17
|
if (!projectName || projectName.includes("/") || projectName.includes("\\") || projectName === "..") this.error(`Invalid project name: "${projectName}"`, { exit: 1 });
|
|
18
18
|
this.log(`\nInitializing project ${chalk.bold(projectName)}...\n`);
|
|
@@ -20,7 +20,8 @@ var Init = class extends BaseCommand {
|
|
|
20
20
|
projectName,
|
|
21
21
|
targetDir: process.cwd(),
|
|
22
22
|
apiUrl,
|
|
23
|
-
token
|
|
23
|
+
token,
|
|
24
|
+
organizationId
|
|
24
25
|
}).catch((err) => {
|
|
25
26
|
if (err instanceof ApiError) {
|
|
26
27
|
this.log(chalk.red(`\nAPI error: ${err.status} ${err.statusText}`));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as loadCredentials, m as unwrap, p as createApiClient, y as getConfig } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { M as loadCredentials, m as unwrap, p as createApiClient, y as getConfig } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
//#region src/adapters/oclif/commands/org/current.ts
|
|
4
4
|
var OrgCurrent = class extends BaseCommand {
|
|
5
5
|
static description = "Show currently selected organization";
|
|
@@ -23,7 +23,7 @@ var OrgCurrent = class extends BaseCommand {
|
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
try {
|
|
26
|
-
const current = unwrap(await createApiClient(getConfig()).organizations.list()).find((o) => o.id === credentials.organizationId) ?? null;
|
|
26
|
+
const current = unwrap(await createApiClient(await getConfig()).organizations.list()).find((o) => o.id === credentials.organizationId) ?? null;
|
|
27
27
|
if (!this.jsonEnabled()) if (current) this.log(`Current organization: ${current.name} (${current.id})`);
|
|
28
28
|
else this.log(`Current organization ID: ${credentials.organizationId}`);
|
|
29
29
|
return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { m as unwrap, p as createApiClient, y as getConfig } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { m as unwrap, p as createApiClient, y as getConfig } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Flags } from "@oclif/core";
|
|
5
5
|
//#region src/adapters/oclif/commands/org/list.ts
|
|
@@ -12,7 +12,7 @@ var OrgList = class extends BaseCommand {
|
|
|
12
12
|
}) };
|
|
13
13
|
async run() {
|
|
14
14
|
const { flags } = this;
|
|
15
|
-
const config = getConfig();
|
|
15
|
+
const config = await getConfig();
|
|
16
16
|
const organizations = unwrap(await createApiClient(config).organizations.list());
|
|
17
17
|
const result = {
|
|
18
18
|
organizations,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as loadCredentials, N as saveCredentials, m as unwrap, n as selectOrganization, p as createApiClient, y as getConfig } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { M as loadCredentials, N as saveCredentials, m as unwrap, n as selectOrganization, p as createApiClient, y as getConfig } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Args } from "@oclif/core";
|
|
5
5
|
//#region src/adapters/oclif/commands/org/switch.ts
|
|
@@ -11,7 +11,7 @@ var OrgSwitch = class extends BaseCommand {
|
|
|
11
11
|
}) };
|
|
12
12
|
async run() {
|
|
13
13
|
const { args } = this;
|
|
14
|
-
const organizations = unwrap(await createApiClient(getConfig()).organizations.list());
|
|
14
|
+
const organizations = unwrap(await createApiClient(await getConfig()).organizations.list());
|
|
15
15
|
if (organizations.length === 0) this.error("You don't belong to any organizations.", { exit: 1 });
|
|
16
16
|
let selected;
|
|
17
17
|
if (args.id) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { p as createApiClient, r as DiffService, y as getConfig } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { p as createApiClient, r as DiffService, y as getConfig } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Args, Flags } from "@oclif/core";
|
|
5
5
|
//#region src/adapters/oclif/commands/overlays/diff.ts
|
|
@@ -18,7 +18,7 @@ var OverlaysDiff = class extends BaseCommand {
|
|
|
18
18
|
async run() {
|
|
19
19
|
const { flags, args } = this;
|
|
20
20
|
const files = args.files ?? [];
|
|
21
|
-
const result = await new DiffService({ api: createApiClient(getConfig()) }).execute({
|
|
21
|
+
const result = await new DiffService({ api: createApiClient(await getConfig()) }).execute({
|
|
22
22
|
dir: flags.dir,
|
|
23
23
|
files: files.length > 0 ? files : void 0
|
|
24
24
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as PullService, p as createApiClient, y as getConfig } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { a as PullService, p as createApiClient, y as getConfig } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Flags } from "@oclif/core";
|
|
5
5
|
//#region src/adapters/oclif/commands/overlays/pull.ts
|
|
@@ -19,7 +19,7 @@ var OverlaysPull = class extends BaseCommand {
|
|
|
19
19
|
};
|
|
20
20
|
async run() {
|
|
21
21
|
const { flags } = this;
|
|
22
|
-
const result = await new PullService({ api: createApiClient(getConfig()) }).execute({
|
|
22
|
+
const result = await new PullService({ api: createApiClient(await getConfig()) }).execute({
|
|
23
23
|
dir: flags.dir,
|
|
24
24
|
names: flags.name
|
|
25
25
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { o as PushService, p as createApiClient, y as getConfig } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { o as PushService, p as createApiClient, y as getConfig } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Args, Flags } from "@oclif/core";
|
|
5
5
|
//#region src/adapters/oclif/commands/overlays/push.ts
|
|
@@ -25,7 +25,7 @@ var OverlaysPush = class extends BaseCommand {
|
|
|
25
25
|
async run() {
|
|
26
26
|
const { flags, args } = this;
|
|
27
27
|
const files = args.files ?? [];
|
|
28
|
-
const result = await new PushService({ api: createApiClient(getConfig()) }).execute({
|
|
28
|
+
const result = await new PushService({ api: createApiClient(await getConfig()) }).execute({
|
|
29
29
|
dir: flags.dir,
|
|
30
30
|
force: flags.force,
|
|
31
31
|
files: files.length > 0 ? files : void 0
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as StatusService, p as createApiClient, y as getConfig } from "../../../../core-
|
|
2
|
-
import { t as BaseCommand } from "../../../../base.command-
|
|
1
|
+
import { i as StatusService, p as createApiClient, y as getConfig } from "../../../../core-Dq15hO6f.mjs";
|
|
2
|
+
import { t as BaseCommand } from "../../../../base.command-DlYMawJ6.mjs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Args, Flags } from "@oclif/core";
|
|
5
5
|
//#region src/adapters/oclif/commands/overlays/status.ts
|
|
@@ -32,7 +32,7 @@ var OverlaysStatus = class extends BaseCommand {
|
|
|
32
32
|
async run() {
|
|
33
33
|
const { flags, args } = this;
|
|
34
34
|
const files = args.files ?? [];
|
|
35
|
-
const result = await new StatusService({ api: createApiClient(getConfig()) }).execute({
|
|
35
|
+
const result = await new StatusService({ api: createApiClient(await getConfig()) }).execute({
|
|
36
36
|
dir: flags.dir,
|
|
37
37
|
files: files.length > 0 ? files : void 0
|
|
38
38
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as setClerkEnv, P as ApiError } from "./core-
|
|
1
|
+
import { E as setClerkEnv, P as ApiError } from "./core-Dq15hO6f.mjs";
|
|
2
2
|
import { Command, Flags } from "@oclif/core";
|
|
3
3
|
import { makeTable } from "@oclif/table";
|
|
4
4
|
//#region src/adapters/oclif/base.command.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import * as os from "os";
|
|
4
|
-
import
|
|
4
|
+
import { createServer } from "node:http";
|
|
5
5
|
import * as crypto from "crypto";
|
|
6
6
|
import { Client, client } from "@revos/api-client";
|
|
7
7
|
import search from "@inquirer/search";
|
|
@@ -72,7 +72,6 @@ async function startOAuthServer() {
|
|
|
72
72
|
}
|
|
73
73
|
function tryStartServer(port) {
|
|
74
74
|
return new Promise((resolve, reject) => {
|
|
75
|
-
const app = express();
|
|
76
75
|
let callbackResolve;
|
|
77
76
|
let callbackReject;
|
|
78
77
|
let timeoutId;
|
|
@@ -80,28 +79,37 @@ function tryStartServer(port) {
|
|
|
80
79
|
callbackResolve = res;
|
|
81
80
|
callbackReject = rej;
|
|
82
81
|
});
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
const server = createServer((req, res) => {
|
|
83
|
+
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
84
|
+
if (url.pathname !== "/callback" || req.method !== "GET") {
|
|
85
|
+
res.writeHead(404);
|
|
86
|
+
res.end();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const code = url.searchParams.get("code") ?? void 0;
|
|
90
|
+
const state = url.searchParams.get("state") ?? void 0;
|
|
91
|
+
const error = url.searchParams.get("error") ?? void 0;
|
|
92
|
+
const errorDescription = url.searchParams.get("error_description") ?? void 0;
|
|
88
93
|
if (error) {
|
|
89
|
-
res.
|
|
94
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
95
|
+
res.end(getErrorHtml(errorDescription || error));
|
|
90
96
|
callbackReject(new Error(errorDescription || error));
|
|
91
97
|
return;
|
|
92
98
|
}
|
|
93
99
|
if (!code || !state) {
|
|
94
|
-
res.
|
|
100
|
+
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
101
|
+
res.end(getErrorHtml("Missing code or state parameter"));
|
|
95
102
|
callbackReject(/* @__PURE__ */ new Error("Missing code or state parameter"));
|
|
96
103
|
return;
|
|
97
104
|
}
|
|
98
|
-
res.
|
|
105
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
106
|
+
res.end(getSuccessHtml());
|
|
99
107
|
callbackResolve({
|
|
100
108
|
code,
|
|
101
109
|
state
|
|
102
110
|
});
|
|
103
111
|
});
|
|
104
|
-
|
|
112
|
+
server.listen(port, () => {
|
|
105
113
|
const shutdown = () => {
|
|
106
114
|
clearTimeout(timeoutId);
|
|
107
115
|
server.close();
|
|
@@ -136,6 +144,8 @@ function getSuccessHtml() {
|
|
|
136
144
|
<!DOCTYPE html>
|
|
137
145
|
<html>
|
|
138
146
|
<head>
|
|
147
|
+
<meta charset="utf-8">
|
|
148
|
+
<link rel="icon" href="https://www.revos.ai/favicons/favicon.ico">
|
|
139
149
|
<title>RevOS CLI - Authentication Successful</title>
|
|
140
150
|
<style>
|
|
141
151
|
body {
|
|
@@ -177,6 +187,8 @@ function getErrorHtml(message) {
|
|
|
177
187
|
<!DOCTYPE html>
|
|
178
188
|
<html>
|
|
179
189
|
<head>
|
|
190
|
+
<meta charset="utf-8">
|
|
191
|
+
<link rel="icon" href="https://www.revos.ai/favicons/favicon.ico">
|
|
180
192
|
<title>RevOS CLI - Authentication Failed</title>
|
|
181
193
|
<style>
|
|
182
194
|
body {
|
|
@@ -330,17 +342,26 @@ async function refreshAccessToken(refreshToken) {
|
|
|
330
342
|
//#endregion
|
|
331
343
|
//#region src/core/config.ts
|
|
332
344
|
const DEFAULT_API_URL = "https://api.revos.ai";
|
|
333
|
-
function getStoredAccessToken() {
|
|
345
|
+
async function getStoredAccessToken() {
|
|
334
346
|
const credentials = loadCredentials();
|
|
335
347
|
if (!credentials) return null;
|
|
336
|
-
if (isTokenExpired(credentials)) return
|
|
337
|
-
|
|
348
|
+
if (!isTokenExpired(credentials)) return credentials.accessToken;
|
|
349
|
+
if (!credentials.refreshToken) return null;
|
|
350
|
+
try {
|
|
351
|
+
const tokenResponse = await refreshAccessToken(credentials.refreshToken);
|
|
352
|
+
const newCredentials = tokenResponseToCredentials(tokenResponse, await getUserInfo(tokenResponse.access_token));
|
|
353
|
+
newCredentials.organizationId = credentials.organizationId;
|
|
354
|
+
saveCredentials(newCredentials);
|
|
355
|
+
return newCredentials.accessToken;
|
|
356
|
+
} catch {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
338
359
|
}
|
|
339
360
|
function getStoredOrganizationId() {
|
|
340
361
|
return loadCredentials()?.organizationId ?? void 0;
|
|
341
362
|
}
|
|
342
|
-
function getConfig() {
|
|
343
|
-
const token = process.env.REVOS_TOKEN || getStoredAccessToken();
|
|
363
|
+
async function getConfig() {
|
|
364
|
+
const token = process.env.REVOS_TOKEN || await getStoredAccessToken();
|
|
344
365
|
if (!token) throw new Error("Not authenticated. Run 'revos auth login' or set REVOS_TOKEN environment variable.");
|
|
345
366
|
return {
|
|
346
367
|
apiUrl: process.env.REVOS_API_URL || DEFAULT_API_URL,
|
|
@@ -785,10 +806,10 @@ var InitService = class {
|
|
|
785
806
|
this.templatesDir = templatesDir;
|
|
786
807
|
}
|
|
787
808
|
async run(options) {
|
|
788
|
-
const { projectName, targetDir, apiUrl, token } = options;
|
|
809
|
+
const { projectName, targetDir, apiUrl, token, organizationId } = options;
|
|
789
810
|
const projectDir = path.join(targetDir, projectName);
|
|
790
811
|
const projectSlug = projectName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
791
|
-
const org = await this.resolveOrganization(apiUrl, token);
|
|
812
|
+
const org = await this.resolveOrganization(apiUrl, token, organizationId);
|
|
792
813
|
const gcpProjectId = await this.downloadGcpKey(apiUrl, token, org, projectSlug);
|
|
793
814
|
const resolvedOrg = {
|
|
794
815
|
...org,
|
|
@@ -801,11 +822,16 @@ var InitService = class {
|
|
|
801
822
|
createdFiles: this.scaffold(projectDir, projectName, projectSlug, resolvedOrg)
|
|
802
823
|
};
|
|
803
824
|
}
|
|
804
|
-
async resolveOrganization(apiUrl, token) {
|
|
825
|
+
async resolveOrganization(apiUrl, token, organizationId) {
|
|
805
826
|
const api = createApiClient({
|
|
806
827
|
apiUrl,
|
|
807
828
|
token
|
|
808
829
|
});
|
|
830
|
+
if (organizationId) {
|
|
831
|
+
const full = unwrap(await api.organizations.get({ id: organizationId }));
|
|
832
|
+
if (!full.bqDataset) throw new Error("Organization is missing BigQuery dataset configuration. Contact support.");
|
|
833
|
+
return full;
|
|
834
|
+
}
|
|
809
835
|
const orgs = unwrap(await api.organizations.list()) ?? [];
|
|
810
836
|
if (orgs.length === 0) throw new Error("No organizations found for this account.");
|
|
811
837
|
const selected = orgs.length === 1 ? orgs[0] : await selectOrganization(orgs);
|
|
@@ -836,36 +862,45 @@ var InitService = class {
|
|
|
836
862
|
const created = [];
|
|
837
863
|
for (const dir of [
|
|
838
864
|
".devcontainer",
|
|
839
|
-
".
|
|
840
|
-
".claude/skills",
|
|
865
|
+
".claude/skills/explore-lakehouse",
|
|
866
|
+
".claude/skills/create-semantic-model",
|
|
841
867
|
"dbt/models/bronze",
|
|
842
868
|
"dbt/models/silver",
|
|
843
869
|
"dbt/models/gold",
|
|
844
|
-
"semantic/cubes"
|
|
845
|
-
"semantic/views"
|
|
870
|
+
"semantic/cubes"
|
|
846
871
|
]) fs.mkdirSync(path.join(projectDir, dir), { recursive: true });
|
|
872
|
+
const dbtName = projectName.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
847
873
|
const files = {
|
|
848
|
-
".devcontainer/devcontainer.json": this.
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
"
|
|
874
|
+
".devcontainer/devcontainer.json": this.renderTemplate(".devcontainer/devcontainer.json", {
|
|
875
|
+
projectName,
|
|
876
|
+
projectSlug,
|
|
877
|
+
bqProjectId: org.bqProjectId || "",
|
|
878
|
+
bqDataset: org.bqDataset,
|
|
879
|
+
organizationId: org.id
|
|
880
|
+
}),
|
|
881
|
+
".devcontainer/Dockerfile": this.renderTemplate(".devcontainer/Dockerfile", {}),
|
|
882
|
+
".devcontainer/setup.sh": this.renderTemplate(".devcontainer/setup.sh", {}),
|
|
883
|
+
".gitignore": this.renderTemplate(".gitignore", {}),
|
|
884
|
+
"README.md": this.renderTemplate("README.md", {
|
|
856
885
|
projectName,
|
|
857
886
|
orgName: org.name
|
|
858
887
|
}),
|
|
888
|
+
"dbt/profiles.yml": this.renderTemplate("dbt/profiles.yml", { bqLocation: org.bqLocation ?? "europe-west3" }),
|
|
889
|
+
"dbt/dbt_project.yml": this.renderTemplate("dbt/dbt_project.yml", { dbtName }),
|
|
890
|
+
"CLAUDE.md": this.renderTemplate("CLAUDE.md", {}),
|
|
859
891
|
"AGENTS.md": this.renderTemplate("AGENTS.md", {
|
|
860
892
|
projectName,
|
|
861
893
|
orgName: org.name
|
|
862
894
|
}),
|
|
863
|
-
".claude/skills
|
|
895
|
+
".claude/skills/explore-lakehouse/SKILL.md": this.renderTemplate("skills/explore-lakehouse/SKILL.md", {
|
|
896
|
+
bqProjectId: org.bqProjectId || "",
|
|
897
|
+
bqDataset: org.bqDataset
|
|
898
|
+
}),
|
|
899
|
+
".claude/skills/create-semantic-model/SKILL.md": this.renderTemplate("skills/create-semantic-model/SKILL.md", {}),
|
|
864
900
|
"dbt/models/bronze/.gitkeep": "",
|
|
865
901
|
"dbt/models/silver/.gitkeep": "",
|
|
866
902
|
"dbt/models/gold/.gitkeep": "",
|
|
867
|
-
"semantic/cubes/.gitkeep": ""
|
|
868
|
-
"semantic/views/.gitkeep": ""
|
|
903
|
+
"semantic/cubes/.gitkeep": ""
|
|
869
904
|
};
|
|
870
905
|
for (const [rel, content] of Object.entries(files)) {
|
|
871
906
|
const full = path.join(projectDir, rel);
|
|
@@ -875,186 +910,13 @@ var InitService = class {
|
|
|
875
910
|
}
|
|
876
911
|
return created;
|
|
877
912
|
}
|
|
878
|
-
renderDbtProfiles(projectName, org) {
|
|
879
|
-
return [
|
|
880
|
-
`${projectName.replace(/[^a-zA-Z0-9_]/g, "_")}:`,
|
|
881
|
-
` target: dev`,
|
|
882
|
-
` outputs:`,
|
|
883
|
-
` dev:`,
|
|
884
|
-
` type: bigquery`,
|
|
885
|
-
` method: service-account`,
|
|
886
|
-
` project: "{{ env_var('GOOGLE_CLOUD_PROJECT') }}"`,
|
|
887
|
-
` dataset: "{{ env_var('REVOS_BQ_DATASET') }}"`,
|
|
888
|
-
` keyfile: "{{ env_var('GOOGLE_APPLICATION_CREDENTIALS') }}"`,
|
|
889
|
-
` threads: 4`,
|
|
890
|
-
` timeout_seconds: 300`,
|
|
891
|
-
` location: ${org.bqLocation ?? "europe-west3"}`,
|
|
892
|
-
``
|
|
893
|
-
].join("\n");
|
|
894
|
-
}
|
|
895
|
-
renderDbtProject(projectName) {
|
|
896
|
-
const dbtName = projectName.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
897
|
-
return [
|
|
898
|
-
`name: "${dbtName}"`,
|
|
899
|
-
`version: "1.0.0"`,
|
|
900
|
-
``,
|
|
901
|
-
`profile: "${dbtName}"`,
|
|
902
|
-
``,
|
|
903
|
-
`model-paths: ["models"]`,
|
|
904
|
-
`seed-paths: ["seeds"]`,
|
|
905
|
-
`test-paths: ["tests"]`,
|
|
906
|
-
`analysis-paths: ["analyses"]`,
|
|
907
|
-
`macro-paths: ["macros"]`,
|
|
908
|
-
``,
|
|
909
|
-
`target-path: "target"`,
|
|
910
|
-
`clean-targets: ["target", "dbt_packages"]`,
|
|
911
|
-
``,
|
|
912
|
-
`models:`,
|
|
913
|
-
` ${dbtName}:`,
|
|
914
|
-
` bronze:`,
|
|
915
|
-
` +materialized: table`,
|
|
916
|
-
` silver:`,
|
|
917
|
-
` +materialized: table`,
|
|
918
|
-
` gold:`,
|
|
919
|
-
` +materialized: table`,
|
|
920
|
-
``
|
|
921
|
-
].join("\n");
|
|
922
|
-
}
|
|
923
|
-
renderRevosEnv(org) {
|
|
924
|
-
return [
|
|
925
|
-
`export GOOGLE_CLOUD_PROJECT="${org.bqProjectId || ""}"`,
|
|
926
|
-
`export REVOS_BQ_DATASET="${org.bqDataset}"`,
|
|
927
|
-
``
|
|
928
|
-
].join("\n");
|
|
929
|
-
}
|
|
930
|
-
renderDevcontainer(projectName, projectSlug) {
|
|
931
|
-
const config = {
|
|
932
|
-
name: `${projectName} — RevOS Data Engineer`,
|
|
933
|
-
image: "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
|
|
934
|
-
features: {
|
|
935
|
-
"ghcr.io/devcontainers/features/python:1": { version: "3.11" },
|
|
936
|
-
"ghcr.io/devcontainers/features/node:1": { version: "lts" },
|
|
937
|
-
"ghcr.io/anthropics/devcontainer-features/claude-code:1": {}
|
|
938
|
-
},
|
|
939
|
-
postCreateCommand: "bash .devcontainer/setup.sh",
|
|
940
|
-
mounts: [{
|
|
941
|
-
source: `\${localEnv:HOME}/.revos/${projectSlug}-gsa-creds.json`,
|
|
942
|
-
target: "/tmp/.revos-gsa-creds.json",
|
|
943
|
-
type: "bind"
|
|
944
|
-
}],
|
|
945
|
-
customizations: { vscode: {
|
|
946
|
-
extensions: ["anthropics.claude-code", "innoverio.vscode-dbt-power-user"],
|
|
947
|
-
settings: { "python.defaultInterpreterPath": "/usr/local/python/current/bin/python" }
|
|
948
|
-
} }
|
|
949
|
-
};
|
|
950
|
-
return JSON.stringify(config, null, 2) + "\n";
|
|
951
|
-
}
|
|
952
|
-
renderSetupScript() {
|
|
953
|
-
return [
|
|
954
|
-
"#!/usr/bin/env bash",
|
|
955
|
-
"set -euo pipefail",
|
|
956
|
-
"",
|
|
957
|
-
"# Google Cloud CLI",
|
|
958
|
-
"curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg \\",
|
|
959
|
-
" | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg",
|
|
960
|
-
"echo \"deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main\" \\",
|
|
961
|
-
" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list",
|
|
962
|
-
"sudo apt-get update -q",
|
|
963
|
-
"sudo apt-get install -y google-cloud-cli",
|
|
964
|
-
"",
|
|
965
|
-
"# dbt (cryptography<47 avoids Illegal instruction on ARM)",
|
|
966
|
-
"pip install --quiet dbt-bigquery \"cryptography<47\"",
|
|
967
|
-
"",
|
|
968
|
-
"# Copy mounted GCP service account key to vscode user's home",
|
|
969
|
-
"if [ -f /tmp/.revos-gsa-creds.json ]; then",
|
|
970
|
-
" mkdir -p \"$HOME/.revos\"",
|
|
971
|
-
" cp /tmp/.revos-gsa-creds.json \"$HOME/.revos/gsa-creds.json\"",
|
|
972
|
-
" chmod 600 \"$HOME/.revos/gsa-creds.json\"",
|
|
973
|
-
"fi",
|
|
974
|
-
"",
|
|
975
|
-
"# Source project-specific env (BQ project, dataset, location)",
|
|
976
|
-
"if [ -f \".revos/env\" ]; then",
|
|
977
|
-
" # shellcheck source=/dev/null",
|
|
978
|
-
" . \".revos/env\"",
|
|
979
|
-
" grep -v \"^#\" \".revos/env\" >> \"$HOME/.bashrc\"",
|
|
980
|
-
"fi",
|
|
981
|
-
"",
|
|
982
|
-
"# Configure gcloud with service account and project",
|
|
983
|
-
"GCP_KEY=\"$HOME/.revos/gsa-creds.json\"",
|
|
984
|
-
"if [ -f \"$GCP_KEY\" ]; then",
|
|
985
|
-
" gcloud auth activate-service-account --key-file=\"$GCP_KEY\"",
|
|
986
|
-
" echo \"export GOOGLE_APPLICATION_CREDENTIALS=\\\"$GCP_KEY\\\"\" >> \"$HOME/.bashrc\"",
|
|
987
|
-
"fi",
|
|
988
|
-
"if [ -n \"${GOOGLE_CLOUD_PROJECT:-}\" ]; then",
|
|
989
|
-
" gcloud config set project \"$GOOGLE_CLOUD_PROJECT\"",
|
|
990
|
-
"fi",
|
|
991
|
-
"",
|
|
992
|
-
"# Symlink dbt profiles so `dbt run` works without --profiles-dir",
|
|
993
|
-
"mkdir -p \"$HOME/.dbt\"",
|
|
994
|
-
"ln -sf \"$(pwd)/dbt/profiles.yml\" \"$HOME/.dbt/profiles.yml\"",
|
|
995
|
-
""
|
|
996
|
-
].join("\n");
|
|
997
|
-
}
|
|
998
|
-
renderGitignore() {
|
|
999
|
-
return [
|
|
1000
|
-
"# dbt",
|
|
1001
|
-
"dbt/target/",
|
|
1002
|
-
"dbt/logs/",
|
|
1003
|
-
"dbt/dbt_packages/",
|
|
1004
|
-
"dbt/profiles.yml",
|
|
1005
|
-
"",
|
|
1006
|
-
"# Python",
|
|
1007
|
-
"__pycache__/",
|
|
1008
|
-
"*.py[cod]",
|
|
1009
|
-
".venv/",
|
|
1010
|
-
"venv/",
|
|
1011
|
-
"",
|
|
1012
|
-
"# Node",
|
|
1013
|
-
"node_modules/",
|
|
1014
|
-
"",
|
|
1015
|
-
"# Local env",
|
|
1016
|
-
".env",
|
|
1017
|
-
".env.*",
|
|
1018
|
-
"!.env.example",
|
|
1019
|
-
""
|
|
1020
|
-
].join("\n");
|
|
1021
|
-
}
|
|
1022
913
|
renderTemplate(relativePath, vars) {
|
|
1023
914
|
const filePath = path.join(this.templatesDir, relativePath);
|
|
1024
915
|
if (!fs.existsSync(filePath)) throw new Error(`Template "${relativePath}" not found — try reinstalling the revos CLI`);
|
|
1025
916
|
let content = fs.readFileSync(filePath, "utf-8");
|
|
1026
|
-
for (const [key, value] of Object.entries(vars)) content = content.replaceAll(
|
|
917
|
+
for (const [key, value] of Object.entries(vars)) content = content.replaceAll(`<%=${key}%>`, value);
|
|
1027
918
|
return content;
|
|
1028
919
|
}
|
|
1029
|
-
renderReadme(projectName, org) {
|
|
1030
|
-
return [
|
|
1031
|
-
`# ${projectName}`,
|
|
1032
|
-
``,
|
|
1033
|
-
`RevOS data engineering project for **${org.name}**.`,
|
|
1034
|
-
``,
|
|
1035
|
-
`## Getting started`,
|
|
1036
|
-
``,
|
|
1037
|
-
`1. Open this folder in VS Code and click **Reopen in Container** — the Dev Container installs all tools automatically.`,
|
|
1038
|
-
`2. Inside the container, verify your setup:`,
|
|
1039
|
-
` \`\`\`bash`,
|
|
1040
|
-
` dbt --version`,
|
|
1041
|
-
` bq version`,
|
|
1042
|
-
` \`\`\``,
|
|
1043
|
-
``,
|
|
1044
|
-
`## Project structure`,
|
|
1045
|
-
``,
|
|
1046
|
-
`\`\`\``,
|
|
1047
|
-
`dbt/models/`,
|
|
1048
|
-
` bronze/ # raw ingested data`,
|
|
1049
|
-
` silver/ # cleaned & conformed`,
|
|
1050
|
-
` gold/ # business-ready marts`,
|
|
1051
|
-
`semantic/`,
|
|
1052
|
-
` cubes/ # Cube.dev cube definitions`,
|
|
1053
|
-
` views/ # Cube.dev view definitions`,
|
|
1054
|
-
`\`\`\``,
|
|
1055
|
-
``
|
|
1056
|
-
].join("\n");
|
|
1057
|
-
}
|
|
1058
920
|
};
|
|
1059
921
|
//#endregion
|
|
1060
922
|
export { getCredentialsPath as A, getUserInfo as C, tokenResponseToCredentials as D, setClerkEnv as E, loadCredentials as M, saveCredentials as N, startOAuthServer as O, ApiError as P, generatePKCEChallenge as S, setClerkConfig as T, isContentEqual as _, PullService as a, buildAuthorizationUrl as b, loadOverlayFile as c, loadOverlaysFromDir as d, saveOverlayToFile as f, formatError as g, findRemoteOnlyOverlays as h, StatusService as i, isTokenExpired as j, deleteCredentials as k, loadOverlays as l, unwrap as m, selectOrganization as n, PushService as o, createApiClient as p, DiffService as r, getLocalOverlayNames as s, InitService as t, loadOverlaysByNames as u, sanitizeFileName as v, refreshAccessToken as w, exchangeCodeForTokens as x, getConfig as y };
|
|
@@ -13,7 +13,7 @@ declare class ApiError extends Error {
|
|
|
13
13
|
}
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/core/config.d.ts
|
|
16
|
-
declare function getConfig(): Config
|
|
16
|
+
declare function getConfig(): Promise<Config>;
|
|
17
17
|
//#endregion
|
|
18
18
|
//#region src/core/auth/credentials-store.d.ts
|
|
19
19
|
declare function getCredentialsPath(): string;
|
|
@@ -161,6 +161,7 @@ interface InitOptions {
|
|
|
161
161
|
targetDir: string;
|
|
162
162
|
apiUrl: string;
|
|
163
163
|
token: string;
|
|
164
|
+
organizationId?: string;
|
|
164
165
|
}
|
|
165
166
|
interface InitResult {
|
|
166
167
|
projectDir: string;
|
|
@@ -174,14 +175,7 @@ declare class InitService {
|
|
|
174
175
|
private resolveOrganization;
|
|
175
176
|
private downloadGcpKey;
|
|
176
177
|
private scaffold;
|
|
177
|
-
private renderDbtProfiles;
|
|
178
|
-
private renderDbtProject;
|
|
179
|
-
private renderRevosEnv;
|
|
180
|
-
private renderDevcontainer;
|
|
181
|
-
private renderSetupScript;
|
|
182
|
-
private renderGitignore;
|
|
183
178
|
private renderTemplate;
|
|
184
|
-
private renderReadme;
|
|
185
179
|
}
|
|
186
180
|
//#endregion
|
|
187
181
|
export { ClerkEnv as A, tokenResponseToCredentials as B, LoadedOverlay as C, loadOverlaysByNames as D, loadOverlays as E, generatePKCEChallenge as F, isTokenExpired as G, startOAuthServer as H, getUserInfo as I, getConfig as J, loadCredentials as K, refreshAccessToken as L, PKCEChallenge as M, buildAuthorizationUrl as N, loadOverlaysFromDir as O, exchangeCodeForTokens as P, setClerkConfig as R, sanitizeFileName as S, loadOverlayFile as T, deleteCredentials as U, OAuthServerResult as V, getCredentialsPath as W, ApiError as Y, createApiClient as _, DiffOptions as a, formatError as b, StatusOptions as c, PullOptions as d, PullService as f, ApiClient as g, PushService as h, DiffContext as i, ClerkOAuthConfig as j, saveOverlayToFile as k, StatusService as l, PushOptions as m, InitResult as n, DiffService as o, PushContext as p, saveCredentials as q, InitService as r, StatusContext as s, InitOptions as t, PullContext as u, unwrap as v, getLocalOverlayNames as w, isContentEqual as x, findRemoteOnlyOverlays as y, setClerkEnv as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { a as DiffEntry, c as OverlayStatusInfo, d as StatusResult, f as SyncStatus, i as DiffChange, l as PullResult, n as CubeDefinition, o as DiffResult, r as CubeOverlay, s as OverlayFile, t as Config, u as PushResult } from "./types-DZssnweO.mjs";
|
|
2
|
-
import { A as ClerkEnv, B as tokenResponseToCredentials, C as LoadedOverlay, D as loadOverlaysByNames, E as loadOverlays, F as generatePKCEChallenge, G as isTokenExpired, H as startOAuthServer, I as getUserInfo, J as getConfig, K as loadCredentials, L as refreshAccessToken, M as PKCEChallenge, N as buildAuthorizationUrl, O as loadOverlaysFromDir, P as exchangeCodeForTokens, R as setClerkConfig, S as sanitizeFileName, T as loadOverlayFile, U as deleteCredentials, V as OAuthServerResult, W as getCredentialsPath, Y as ApiError, _ as createApiClient, a as DiffOptions, b as formatError, c as StatusOptions, d as PullOptions, f as PullService, g as ApiClient, h as PushService, i as DiffContext, j as ClerkOAuthConfig, k as saveOverlayToFile, l as StatusService, m as PushOptions, n as InitResult, o as DiffService, p as PushContext, q as saveCredentials, r as InitService, s as StatusContext, t as InitOptions, u as PullContext, v as unwrap, w as getLocalOverlayNames, x as isContentEqual, y as findRemoteOnlyOverlays, z as setClerkEnv } from "./index-
|
|
2
|
+
import { A as ClerkEnv, B as tokenResponseToCredentials, C as LoadedOverlay, D as loadOverlaysByNames, E as loadOverlays, F as generatePKCEChallenge, G as isTokenExpired, H as startOAuthServer, I as getUserInfo, J as getConfig, K as loadCredentials, L as refreshAccessToken, M as PKCEChallenge, N as buildAuthorizationUrl, O as loadOverlaysFromDir, P as exchangeCodeForTokens, R as setClerkConfig, S as sanitizeFileName, T as loadOverlayFile, U as deleteCredentials, V as OAuthServerResult, W as getCredentialsPath, Y as ApiError, _ as createApiClient, a as DiffOptions, b as formatError, c as StatusOptions, d as PullOptions, f as PullService, g as ApiClient, h as PushService, i as DiffContext, j as ClerkOAuthConfig, k as saveOverlayToFile, l as StatusService, m as PushOptions, n as InitResult, o as DiffService, p as PushContext, q as saveCredentials, r as InitService, s as StatusContext, t as InitOptions, u as PullContext, v as unwrap, w as getLocalOverlayNames, x as isContentEqual, y as findRemoteOnlyOverlays, z as setClerkEnv } from "./index-DuqD2b_7.mjs";
|
|
3
3
|
import { a as OrgListResult, c as StoredCredentials, i as OAuthCallbackResult, l as TokenResponse, n as AuthStatusInfo, o as OrgSwitchResult, r as ClerkUserInfo, s as OrganizationInfo, t as AuthResult } from "./types-DsQtGF-c.mjs";
|
|
4
4
|
export { ApiClient, ApiError, AuthResult, AuthStatusInfo, ClerkEnv, ClerkOAuthConfig, ClerkUserInfo, Config, CubeDefinition, CubeOverlay, DiffChange, DiffContext, DiffEntry, DiffOptions, DiffResult, DiffService, InitOptions, InitResult, InitService, LoadedOverlay, OAuthCallbackResult, OAuthServerResult, OrgListResult, OrgSwitchResult, OrganizationInfo, OverlayFile, OverlayStatusInfo, PKCEChallenge, PullContext, PullOptions, PullResult, PullService, PushContext, PushOptions, PushResult, PushService, StatusContext, StatusOptions, StatusResult, StatusService, StoredCredentials, SyncStatus, TokenResponse, buildAuthorizationUrl, createApiClient, deleteCredentials, exchangeCodeForTokens, findRemoteOnlyOverlays, formatError, generatePKCEChallenge, getConfig, getCredentialsPath, getLocalOverlayNames, getUserInfo, isContentEqual, isTokenExpired, loadCredentials, loadOverlayFile, loadOverlays, loadOverlaysByNames, loadOverlaysFromDir, refreshAccessToken, sanitizeFileName, saveCredentials, saveOverlayToFile, setClerkConfig, setClerkEnv, startOAuthServer, tokenResponseToCredentials, unwrap };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as getCredentialsPath, C as getUserInfo, D as tokenResponseToCredentials, E as setClerkEnv, M as loadCredentials, N as saveCredentials, O as startOAuthServer, P as ApiError, S as generatePKCEChallenge, T as setClerkConfig, _ as isContentEqual, a as PullService, b as buildAuthorizationUrl, c as loadOverlayFile, d as loadOverlaysFromDir, f as saveOverlayToFile, g as formatError, h as findRemoteOnlyOverlays, i as StatusService, j as isTokenExpired, k as deleteCredentials, l as loadOverlays, m as unwrap, o as PushService, p as createApiClient, r as DiffService, s as getLocalOverlayNames, t as InitService, u as loadOverlaysByNames, v as sanitizeFileName, w as refreshAccessToken, x as exchangeCodeForTokens, y as getConfig } from "./core-
|
|
1
|
+
import { A as getCredentialsPath, C as getUserInfo, D as tokenResponseToCredentials, E as setClerkEnv, M as loadCredentials, N as saveCredentials, O as startOAuthServer, P as ApiError, S as generatePKCEChallenge, T as setClerkConfig, _ as isContentEqual, a as PullService, b as buildAuthorizationUrl, c as loadOverlayFile, d as loadOverlaysFromDir, f as saveOverlayToFile, g as formatError, h as findRemoteOnlyOverlays, i as StatusService, j as isTokenExpired, k as deleteCredentials, l as loadOverlays, m as unwrap, o as PushService, p as createApiClient, r as DiffService, s as getLocalOverlayNames, t as InitService, u as loadOverlaysByNames, v as sanitizeFileName, w as refreshAccessToken, x as exchangeCodeForTokens, y as getConfig } from "./core-Dq15hO6f.mjs";
|
|
2
2
|
export { ApiError, DiffService, InitService, PullService, PushService, StatusService, buildAuthorizationUrl, createApiClient, deleteCredentials, exchangeCodeForTokens, findRemoteOnlyOverlays, formatError, generatePKCEChallenge, getConfig, getCredentialsPath, getLocalOverlayNames, getUserInfo, isContentEqual, isTokenExpired, loadCredentials, loadOverlayFile, loadOverlays, loadOverlaysByNames, loadOverlaysFromDir, refreshAccessToken, sanitizeFileName, saveCredentials, saveOverlayToFile, setClerkConfig, setClerkEnv, startOAuthServer, tokenResponseToCredentials, unwrap };
|