Skip to content

Commit

Permalink
Merge branch 'v3' into v3-hints
Browse files Browse the repository at this point in the history
  • Loading branch information
ecooper authored Dec 10, 2024
2 parents 053d765 + b1f1cbd commit baab734
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 92 deletions.
2 changes: 1 addition & 1 deletion src/commands/schema/diff.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { reformatFSL } from "../../lib/schema.mjs";
import { localSchemaOptions } from "./schema.mjs";

/**
* @returns string[]
* @returns {[string, string]} An tuple containing the source and target schema
*/
function parseTarget(argv) {
if (!argv.active && !argv.staged) {
Expand Down
63 changes: 34 additions & 29 deletions src/commands/schema/pull.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
//@ts-check

import { container } from "../../cli.mjs";
import {
CommandError,
yargsWithCommonQueryOptions,
} from "../../lib/command-helpers.mjs";
import { yargsWithCommonQueryOptions } from "../../lib/command-helpers.mjs";
import { getSecret } from "../../lib/fauna-client.mjs";
import { localSchemaOptions } from "./schema.mjs";

Expand Down Expand Up @@ -36,9 +33,9 @@ async function determineFileState(argv, filenames) {
return { adds, deletes, existing, overwrites };
}

function logDiff({ argv, adds, overwrites, deletes }) {
function logDiff({ argv, adds, overwrites, deletes, source }) {
const logger = container.resolve("logger");
logger.stdout("Pull will make the following changes:");
logger.stdout(`Pulling ${source} schema will make the following changes:`);
if (argv.delete) {
for (const deleteme of deletes) {
logger.stdout(`delete: ${deleteme}`);
Expand All @@ -58,10 +55,29 @@ async function doPull(argv) {
const makeFaunaRequest = container.resolve("makeFaunaRequest");
const secret = await getSecret();

// Get the staged schema status
/** @type {{ status: "none" | "pending" | "ready" | "failed", version: string }} */
const statusResponse = await makeFaunaRequest({
argv,
path: "/schema/1/staged/status",
method: "GET",
secret,
});

const version = statusResponse.version;
const source =
argv.active || statusResponse.status === "none" ? "active" : "staged";

const filesParams = new URLSearchParams({
version,
staged: source === "staged" ? "true" : "false",
});

// fetch the list of remote FSL files
const filesResponse = await makeFaunaRequest({
argv,
path: "/schema/1/files",
params: filesParams,
method: "GET",
secret,
});
Expand All @@ -72,31 +88,16 @@ async function doPull(argv) {
.filter((name) => name.endsWith(".fsl"))
.sort();

// check if there's a staged schema
const statusResponse = await makeFaunaRequest({
argv,
path: "/schema/1/staged/status",
params: new URLSearchParams({ version: filesResponse.version }),
method: "GET",
secret,
});

// if there's a staged schema, cannot use the --active flag.
// getting active FSL while staged FSL exists is not yet
// implemented at the service level.
if (statusResponse.status !== "none" && argv.active) {
throw new CommandError(
"There is a staged schema change. Remove the --active flag to pull it.",
);
} else if (statusResponse.status === "none" && !argv.active) {
throw new CommandError("There are no staged schema changes to pull.");
}
logger.debug(
`Pulling remote ${source} schema, version '${version}'.`,
"schema-pull",
);

const { adds, deletes, overwrites } = await determineFileState(
argv,
filenames,
);
logDiff({ argv, adds, deletes, overwrites });
logDiff({ argv, adds, deletes, overwrites, source });

const confirmed = await confirm({
message: "Accept the changes?",
Expand All @@ -108,7 +109,12 @@ async function doPull(argv) {
const getAllSchemaFileContents = container.resolve(
"getAllSchemaFileContents",
);
const contents = await getAllSchemaFileContents(filenames, argv);
const contents = await getAllSchemaFileContents(
filenames,
source,
version,
argv,
);

// don't start writing or deleting files until we've successfully fetched all
// the remote schema files
Expand Down Expand Up @@ -138,8 +144,7 @@ function buildPullCommand(yargs) {
default: false,
},
active: {
description:
"Pull the database's active schema files. If omitted, pulls the database's staged schema, if available.",
description: "Pull the database's active schema files.",
type: "boolean",
default: false,
},
Expand Down
27 changes: 18 additions & 9 deletions src/lib/auth/credentials.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,24 @@ import { AccountKeys } from "./accountKeys.mjs";
import { DatabaseKeys } from "./databaseKeys.mjs";

const validateCredentialArgs = (argv) => {
if (argv.database && argv.secret && !argv.local) {
throw new ValidationError(
"Cannot use both the '--secret' and '--database' options together. Please specify only one.",
);
} else if (argv.role && argv.secret && !argv.local) {
// The '--role' option is not supported when using a secret. Secrets have an
// implicit role.
throw new ValidationError(
"The '--role' option is not supported when using a '--secret'. Please specify only one.",
const logger = container.resolve("logger");
const illegalArgCombos = [
["accountKey", "secret", "local"],
["secret", "database", "local"],
["secret", "role", "local"],
];
for (const [first, second, conditional] of illegalArgCombos) {
if (argv[first] && argv[second] && !argv[conditional]) {
throw new ValidationError(
`Cannot use both the '--${first}' and '--${second}' options together. Please specify only one.`,
);
}
}

if (argv.user && argv.accountKey) {
logger.debug(
"Both 'user' and 'accountKey' arguments were specified. 'accountKey' will be used to mint database secrets. 'user' will be ignored.",
"creds",
);
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/lib/auth/databaseKeys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class DatabaseKeys {
// argv.secret comes from flag, config, or FAUNA_SECRET
if (argv.secret) {
key = argv.secret;
keySource = "--secret";
keySource = "user";
} else {
key = storedKey;
keySource = "credentials-file";
Expand Down
4 changes: 3 additions & 1 deletion src/lib/command-helpers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ const COMMON_QUERY_OPTIONS = {
},
accountKey: {
type: "string",
description: "The account key to use when calling Fauna",
description:
"Fauna account key used for authentication. Negates the need for a user login. The key is used to generate short-lived database secrets for the CLI. Mutually exclusive with `--user` and `--secret`.",
required: false,
group: "API:",
},
database: {
alias: "d",
Expand Down
16 changes: 15 additions & 1 deletion src/lib/schema.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -167,19 +167,33 @@ export async function writeSchemaFiles(dir, filenameToContentsDict) {

/**
* @param {string[]} filenames - A list of schema file names to fetch
* @param {"active" | "staged"} source - The source to pull from
* @param {string} version - The schema version for optimistic concurrency control
* @param {object} argv
* @returns {Promise<Record<string, string>>} A map of schema file names to their contents.
*/
export async function getAllSchemaFileContents(filenames, argv) {
export async function getAllSchemaFileContents(
filenames,
source,
version,
argv,
) {
const promises = [];
/** @type Record<string, string> */
const fileContentCollection = {};
const secret = await getSecret();

const params = new URLSearchParams({
version: version,
staged: source === "staged" ? "true" : "false",
});

for (const filename of filenames) {
promises.push(
makeFaunaRequest({
argv,
path: `/schema/1/files/${encodeURIComponent(filename)}`,
params,
method: "GET",
secret,
}).then(({ content }) => {
Expand Down
2 changes: 1 addition & 1 deletion test/credentials.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe("credentials", function () {
databaseKeys: {
role: undefined,
key: "user-secret",
keySource: "--secret",
keySource: "user",
},
},
},
Expand Down
Loading

0 comments on commit baab734

Please sign in to comment.