@fragment-dev/cli
Version:
337 lines (334 loc) • 8.73 kB
JavaScript
import {
standardQueries
} from "./chunk-6DAZJ3YI.js";
import {
InvalidGraphQlError
} from "./chunk-73ZTML2E.js";
import {
getSchemaObjectParameters,
getStructuralSubpaths
} from "./chunk-JQCVGUVA.js";
import {
require_parser,
require_printer
} from "./chunk-7K4RMTU4.js";
import {
require_source
} from "./chunk-M5OAS5QZ.js";
import {
__toESM,
init_cjs_shims
} from "./chunk-7GH3YGSC.js";
// src/graphql.ts
init_cjs_shims();
var import_chalk = __toESM(require_source(), 1);
var import_parser = __toESM(require_parser(), 1);
var import_printer = __toESM(require_printer(), 1);
import { statSync, existsSync } from "node:fs";
var schemaToEntryDefinitions = ({
schema
}) => {
return schema.ledgerEntries.types.flatMap((ledgerEntry) => {
const entryParameters = getSchemaObjectParameters(ledgerEntry);
const lineAccountParameters = (ledgerEntry.lines ?? []).flatMap(
(line) => {
const subpaths = getStructuralSubpaths(line.account.path);
return subpaths.flatMap(
(subp) => getSchemaObjectParameters(
schema.chartOfAccounts.accountPathToAccount.get(subp)
)
);
}
);
const conditionAccountParameters = (ledgerEntry.conditions ?? []).flatMap(
(condition) => {
const subpaths = getStructuralSubpaths(
condition.account.path
);
return subpaths.flatMap(
(subp) => getSchemaObjectParameters(
schema.chartOfAccounts.accountPathToAccount.get(subp)
)
);
}
);
const parameters = Array.from(
/* @__PURE__ */ new Set([
...conditionAccountParameters,
...lineAccountParameters,
...entryParameters
])
);
const isReconciliationEntry = (ledgerEntry.lines ?? []).some(
(line) => !!line.tx
);
const isRuntimeEntry = (ledgerEntry.lines ?? []).length === 0;
const codegenInput = {
entryType: ledgerEntry.type,
typeVersion: ledgerEntry.typeVersion,
runtimeEntry: isRuntimeEntry,
parameters
};
if (isRuntimeEntry) {
return [
{
...codegenInput,
method: "reconcileTx"
},
{
...codegenInput,
method: "addLedgerEntry"
}
];
}
return [
{
...codegenInput,
method: isReconciliationEntry ? "reconcileTx" : "addLedgerEntry"
}
];
});
};
var camelCase = (value, delimiter) => {
return value.split(delimiter).filter((x) => !!x).map((word, index) => {
if (index === 0) {
return word;
}
return word[0].toUpperCase() + word.slice(1);
}).join("");
};
var OnErrorFragment = `
... on BadRequestError {
code
message
retryable
}
... on InternalError {
code
message
retryable
}
`;
var LedgerEntryFragment = `
ik
id
created
type
posted
description
ledger {
ik
}
tags {
key
value
}
groups {
key
value
}
`;
var LedgerLineFragment = `
account {
path
}
amount
currency {
code
customCurrencyId
}
key
`;
var AddLedgerEntryFragment = `
__typename
... on AddLedgerEntryResult {
entry {
${LedgerEntryFragment}
}
lines {
${LedgerLineFragment}
}
isIkReplay
}
${OnErrorFragment}
`;
var ReconcileTxFragment = `
__typename
... on ReconcileTxResult {
entry {
${LedgerEntryFragment}
}
lines {
${LedgerLineFragment}
tx {
externalId
externalAccount {
externalId
}
}
}
isIkReplay
}
${OnErrorFragment}
`;
var isValidGraphQlName = (name) => {
return /^[a-zA-Z_]+[a-zA-Z0-9_]*$/.exec(name) !== null;
};
var generateGraphQlEntryType = (entryType, typeVersion) => {
const readableEntryType = camelCase(camelCase(entryType, "_"), "-").split("").map((ch, idx) => {
if (idx === 0) {
return ch.toUpperCase();
}
return ch;
}).join("").replace(/\s+/g, "_").replace(/\./g, "_").replace(/[^a-zA-Z0-9_]/g, "").replace(/^(\d)/, "_$1").concat(typeVersion && typeVersion > 1 ? `_v${typeVersion}` : "");
if (!isValidGraphQlName(readableEntryType)) {
throw new InvalidGraphQlError(
`Operation name ${readableEntryType} (for entry: ${import_chalk.default.yellow(
entryType
)}) is not a valid GraphQL name`
);
}
return readableEntryType;
};
var getPredefinedParameters = (definition) => {
const params = {};
if (definition.method === "addLedgerEntry") {
params["ik"] = "SafeString!";
params["posted"] = "DateTime";
}
if (definition.runtimeEntry) {
params["lines"] = "[LedgerLineInput!]!";
params["tags"] = "[LedgerEntryTagInput!]";
params["groups"] = "[LedgerEntryGroupInput!]";
}
params["ledgerIk"] = "SafeString!";
return params;
};
var entryDefinitionToMutation = (definition) => {
const { typeVersion } = definition;
const predefinedParameters = getPredefinedParameters(definition);
const filteredParameters = definition.parameters.filter(
(p) => !Object.prototype.hasOwnProperty.call(predefinedParameters, p)
);
filteredParameters.forEach((param) => {
if (!isValidGraphQlName(param)) {
throw new InvalidGraphQlError(
`Parameter name ${param} is not a valid GraphQL name`
);
}
});
const readableEntryType = generateGraphQlEntryType(definition.entryType, typeVersion);
const mutationArgs = filteredParameters.map((p) => `$${p}: String!`).join("\n");
const graphQlFragment = definition.method === "addLedgerEntry" ? AddLedgerEntryFragment : ReconcileTxFragment;
const operationPrefix = definition.method === "addLedgerEntry" ? "Post" : "Reconcile";
const isIkRequired = Object.prototype.hasOwnProperty.call(
predefinedParameters,
"ik"
);
const isPostedAllowed = Object.prototype.hasOwnProperty.call(
predefinedParameters,
"posted"
);
const operationName = `${operationPrefix}${readableEntryType}`;
const predefinedArgs = Object.entries(predefinedParameters).map(([name, type]) => `$${name}: ${type}`).join(",\n");
const command = [
// Named mutation with input parameters block
`mutation ${operationName} (`,
`${predefinedArgs},`,
`${mutationArgs}) {`,
// The actual mutation method
`${definition.method}(`,
// The input object
`${isIkRequired ? "ik: $ik," : ""}`,
`entry: {`,
`ledger: { ik: $ledgerIk },`,
`type: "${definition.entryType}",`
];
if (typeVersion !== void 0) {
command.push(`typeVersion: ${typeVersion},`);
}
if (isPostedAllowed) {
command.push(`posted: $posted,`);
}
if (definition.runtimeEntry) {
command.push(`lines: $lines, tags: $tags, groups: $groups,`);
}
if (Object.keys(definition.parameters).length > 0) {
command.push(`parameters: {`);
command.push(definition.parameters.map((p) => `${p}: $${p}`).join("\n"));
command.push(`}`);
}
command.push(`}) { ${graphQlFragment} } }`);
return {
mutation: (0, import_printer.print)((0, import_parser.parse)(command.join(""))),
operationName
};
};
var generateQueriesFileContent = ({
definitions,
includeStandardQueries
}) => {
const generatedCode = definitions.map(
(def) => entryDefinitionToMutation(def).mutation
);
if (includeStandardQueries) {
generatedCode.push(standardQueries);
}
return `${generatedCode.join("\n")}
`;
};
var generateQueryFiles = ({
definitions,
includeStandardQueries
}) => {
const generatedCode = definitions.map((def) => {
const { operationName, mutation } = entryDefinitionToMutation(def);
return {
content: `${mutation}
`,
fileName: `${operationName}.graphql`
};
});
if (includeStandardQueries) {
const parsedStdQueries = (0, import_parser.parse)(standardQueries);
parsedStdQueries.definitions.forEach((def) => {
if (def.kind !== "OperationDefinition") {
return;
}
generatedCode.push({
content: `${(0, import_printer.print)(def)}
`,
fileName: `${def.name.value}.standard-query.graphql`
});
});
}
return generatedCode;
};
var validateOutputName = ({
output,
outputFilePerQuery
}) => {
if (outputFilePerQuery) {
if (!existsSync(output)) {
throw new Error("Output path must exist");
}
if (!statSync(output).isDirectory()) {
throw new Error("Output path must be a directory");
}
} else {
if (/.+\.(graphql|gql)/.exec(output) === null) {
throw new Error("Output name must end with .graphql or .gql");
}
}
};
export {
schemaToEntryDefinitions,
camelCase,
isValidGraphQlName,
generateGraphQlEntryType,
getPredefinedParameters,
entryDefinitionToMutation,
generateQueriesFileContent,
generateQueryFiles,
validateOutputName
};