UNPKG

refine-apito

Version:

A data provider for Refine that connects to Apito - a headless CMS and backend builder.

226 lines (224 loc) 9.46 kB
import { singularize } from 'inflection'; // src/apitoGraphqlNames.ts var singularKeepAsIs = /* @__PURE__ */ new Set([ "news", "data", "media", "analytics", "series", "species" ]); var canonicalIDRe = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/; function rejectRunOnLowercaseConcat(raw) { if (/[\s_\-]/.test(raw)) return; if (/[a-z][A-Z]/.test(raw)) return; if (!/^[a-z]+$/.test(raw)) return; if (raw.length >= 9) { throw new Error( 'model name needs a word boundary between words: use food_order, food-order, foodOrder, or "food order"' ); } } function splitCamelPieces(piece) { const spaced = piece.replace(/([a-z0-9])([A-Z])/g, "$1 $2"); return spaced.split(/\s+/).filter(Boolean).map((s) => s.replace(/[^a-zA-Z0-9]/g, "").toLowerCase()).filter(Boolean); } function splitIntoWordSegments(raw) { const normalized = raw.trim().replace(/-/g, "_"); const chunks = normalized.split(/[\s_]+/).filter((c) => c.length > 0); const segments = []; for (const chunk of chunks) { const lettersOnly = chunk.replace(/[^a-zA-Z0-9]/g, ""); const pieces = lettersOnly === chunk ? splitCamelPieces(chunk) : [lettersOnly.toLowerCase()]; for (const p of pieces) { const s = p.replace(/[^a-z0-9]/gi, "").toLowerCase(); if (s) segments.push(s); } } return segments; } function singularizeSegment(seg) { if (singularKeepAsIs.has(seg)) return seg; return singularize(seg); } function canonicalizeModelName(raw) { const t = raw.trim(); if (!t) throw new Error("model name is required"); rejectRunOnLowercaseConcat(t); const segments = splitIntoWordSegments(t); if (segments.length === 0) throw new Error("invalid model name"); segments[segments.length - 1] = singularizeSegment( segments[segments.length - 1] ); const out = segments.join("_"); if (!canonicalIDRe.test(out)) throw new Error("invalid model name"); reservedCheck(out); return out; } function reservedCheck(canonical) { switch (canonical) { case "list": throw new Error( "naming a Model `List` is not allowed. Apito uses List for plural resources." ); case "user": throw new Error( "naming a Model `User` is protected. Add the Authentication module from Settings." ); case "system": throw new Error("naming a Model `System` is not allowed."); case "function": throw new Error("naming a Model `Function` is not allowed."); } } function camelFromCanonical(canonical) { const parts = canonical.split("_").filter(Boolean); return parts.map( (p, i) => i === 0 ? p.toLowerCase() : p.charAt(0).toUpperCase() + p.slice(1).toLowerCase() ).join(""); } function pascalFromCanonical(canonical) { return canonical.split("_").filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()).join(""); } function pascalFromAnyModelId(modelId) { if (!modelId) return ""; if (modelId.includes("_")) return pascalFromCanonical(modelId); const segs = splitCamelPieces(modelId); return segs.map((s) => s.charAt(0).toUpperCase() + s.slice(1).toLowerCase()).join(""); } function listGraphQLTypeName(modelId) { return `${pascalFromAnyModelId(apitoSingularResourceName(modelId))}List`; } function apitoGraphQLComposedTypeName(modelId, suffix) { const singular = apitoSingularResourceName(modelId); const suf = suffix.replace(/^_/, "").split("_").filter(Boolean); const modelSegs = singular.includes("_") ? singular.split("_").filter(Boolean) : splitCamelPieces(singular).map((s) => s.toLowerCase()); const extra = suf.flatMap( (chunk) => splitCamelPieces(chunk).map((x) => x.toLowerCase()) ); const all = [...modelSegs, ...extra]; return all.map((p) => p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()).join("_"); } function apitoSingularResourceName(name) { let t = name.trim(); if (t.endsWith("ListCount")) t = t.slice(0, -"ListCount".length); else if (t.endsWith("List")) t = t.slice(0, -"List".length); t = t.trim(); if (!t) return ""; if (t.includes("_")) { return camelFromCanonical(t); } const segs = splitCamelPieces(t); if (segs.length === 0) return t.toLowerCase(); return segs.map( (s, i) => i === 0 ? s.toLowerCase() : s.charAt(0).toUpperCase() + s.slice(1).toLowerCase() ).join(""); } var apitoModelName = apitoSingularResourceName; function apitoMultipleResourceName(name) { return `${apitoSingularResourceName(name)}List`; } function apitoConnectionFieldNameForRelation(relatedModelRef, relation) { if (relation === "has_many") { return apitoMultipleResourceName(relatedModelRef); } return apitoSingularResourceName(relatedModelRef); } function apitoGraphqlConnectionFieldFromMetaKey(key) { const k = key.trim(); if (!k) return k; if (k.includes("_")) { return apitoSingularResourceName(k); } if (/List$/i.test(k) && !/ListCount$/i.test(k)) { return k.charAt(0).toLowerCase() + k.slice(1); } return apitoSingularResourceName(k); } function apitoGraphQLTypeNameForFilterArg(modelId) { return listGraphQLTypeName(modelId); } function apitoListGraphQLTypeName(resource) { return listGraphQLTypeName(resource); } function apitoListCountGraphQLTypeName(resource) { return apitoGraphQLComposedTypeName(resource, "List_Count"); } function apitoSingularGraphQLTypeName(resource) { return pascalFromAnyModelId(apitoSingularResourceName(resource)); } function apitoStoredSnakeModelId(resource) { const singular = apitoSingularResourceName(resource); if (singular.includes("_")) return singular; return splitCamelPieces(singular).join("_"); } function apitoMutationConnectHasOneIdField(relatedModelRef) { return `${apitoStoredSnakeModelId(relatedModelRef)}_id`; } function apitoMutationConnectHasManyIdsField(relatedModelRef) { return `${apitoStoredSnakeModelId(relatedModelRef)}_ids`; } function apitoConnectionFilterConditionType(resource) { return `${apitoStoredSnakeModelId(resource)}_Connection_Filter_Condition`.toUpperCase(); } function apitoWhereRelationFilterConditionType(resource) { return `${apitoStoredSnakeModelId(resource)}_Where_Relation_Filter_Condition`.toUpperCase(); } function apitoWhereInputType(resource) { return `${listGraphQLTypeName(resource)}_Input_Where_Payload`.toUpperCase(); } function apitoSortInputType(resource) { return `${listGraphQLTypeName(resource)}_Input_Sort_Payload`.toUpperCase(); } function apitoListKeyConditionType(resource) { return `${listGraphQLTypeName(resource)}_Key_Condition`.toUpperCase(); } function apitoListCountKeyConditionType(resource) { return `${apitoGraphQLComposedTypeName(resource, "List_Count")}_Key_Condition`.toUpperCase(); } function apitoListCountWhereInputType(resource) { return `${apitoGraphQLComposedTypeName(resource, "List_Count")}_Input_Where_Payload`.toUpperCase(); } function apitoListCountSortInputType(resource) { return `${apitoGraphQLComposedTypeName(resource, "List_Count")}_Input_Sort_Payload`.toUpperCase(); } function formatApitoConnectionSubselections(connectionFields, aliasFields = {}) { return Object.keys(connectionFields).map((key) => { const selection = connectionFields[key]; const rawTarget = aliasFields[key]; const hasExplicitAlias = rawTarget !== void 0 && rawTarget !== null && String(rawTarget).trim() !== ""; const targetField = apitoGraphqlConnectionFieldFromMetaKey( hasExplicitAlias ? String(rawTarget).trim() : key ); if (hasExplicitAlias) { const responseKey = key; if (responseKey === targetField) { return `${targetField} { ${selection} }`; } return `${responseKey}: ${targetField} { ${selection} }`; } return `${targetField} { ${selection} }`; }).join("\n"); } function buildApitoCreateMutation(resource, fields) { const id = apitoSingularResourceName(resource); const pascal = pascalFromAnyModelId(id); const payload = apitoGraphQLComposedTypeName(id, "Create_Payload"); const rel = apitoGraphQLComposedTypeName(id, "Relation_Connect_Payload"); return ` mutation Create${pascal}($payload: ${payload}!, $connect: ${rel}) { create${pascal}(payload: $payload, connect: $connect, status: published) { id data { ${fields.join("\n")} } meta { created_at status updated_at } } }`; } export { apitoConnectionFieldNameForRelation, apitoConnectionFilterConditionType, apitoGraphQLComposedTypeName, apitoGraphQLTypeNameForFilterArg, apitoGraphqlConnectionFieldFromMetaKey, apitoListCountGraphQLTypeName, apitoListCountKeyConditionType, apitoListCountSortInputType, apitoListCountWhereInputType, apitoListGraphQLTypeName, apitoListKeyConditionType, apitoModelName, apitoMultipleResourceName, apitoMutationConnectHasManyIdsField, apitoMutationConnectHasOneIdField, apitoSingularGraphQLTypeName, apitoSingularResourceName, apitoSortInputType, apitoStoredSnakeModelId, apitoWhereInputType, apitoWhereRelationFilterConditionType, buildApitoCreateMutation, camelFromCanonical, canonicalizeModelName, formatApitoConnectionSubselections, listGraphQLTypeName, pascalFromAnyModelId, pascalFromCanonical }; //# sourceMappingURL=apitoGraphqlNames.mjs.map //# sourceMappingURL=apitoGraphqlNames.mjs.map