UNPKG

strapi-nextgen-framework

Version:

Production-ready, type-safe framework bridging Strapi v4 CMS and Next.js 14+ App Router with automatic cache management, Error Boundaries, and SEO optimization

166 lines 6.07 kB
"use strict"; /** * Data Layer (SDK) - Phase 2 Implementation * GraphQL-first SDK with automatic cache tagging for Next.js */ Object.defineProperty(exports, "__esModule", { value: true }); exports.createStrapiSDK = void 0; const graphql_request_1 = require("graphql-request"); const fetch_wrapper_1 = require("./fetch-wrapper"); const cache_tags_1 = require("./cache-tags"); const headers_1 = require("next/headers"); /** * Creates a configured Strapi SDK instance * * @param config - SDK configuration options * @returns Configured SDK instance * * @example * ```typescript * const strapiClient = createStrapiSDK({ * url: process.env.STRAPI_URL, * token: process.env.STRAPI_TOKEN, * }); * ``` */ function createStrapiSDK(config) { // Validate required configuration if (!config.url) { throw new Error('Strapi URL is required in SDK configuration'); } // Create base headers const baseHeaders = {}; if (config.token) { baseHeaders.Authorization = `Bearer ${config.token}`; } // Create GraphQL client const client = new graphql_request_1.GraphQLClient(config.url, { headers: baseHeaders, fetch: (0, fetch_wrapper_1.createCacheTaggedFetch)(config.logging), }); // Check if draft mode is active (Next.js 14+) const isDraftMode = () => { try { return (0, headers_1.draftMode)().isEnabled; } catch { // Not in a request context or draft mode not available return false; } }; // Helper to build GraphQL variables with locale and filters const buildVariables = (options) => { const variables = {}; if (options?.locale) { variables.locale = options.locale; } if (options?.filters) { variables.filters = options.filters; } if (options?.sort) { variables.sort = options.sort; } if (options?.pagination) { variables.pagination = options.pagination; } // Add publicationState for draft mode if (isDraftMode()) { variables.publicationState = 'PREVIEW'; } return variables; }; return { /** * Fetch a single page by slug */ async getPage(slug, options) { const tag = (0, cache_tags_1.generateCacheTag)('page', slug, options?.locale); if (config.logging?.queries) { console.log(`[Strapi SDK] getPage: ${slug}`, { tag, options }); } // This is a simplified query - in real usage, developers will use graphql-codegen // to generate typed queries from their .graphql files const query = ` query GetPage($slug: String!, $locale: String, $publicationState: PublicationState) { pages(filters: { slug: { eq: $slug } }, locale: $locale, publicationState: $publicationState) { data { id attributes } } } `; const variables = { slug, ...buildVariables(options) }; // Note: Cache tags are handled by the custom fetch wrapper // graphql-request doesn't support Next.js options directly const data = await client.request(query, variables); const firstPage = data.pages.data[0]; if (!firstPage) { throw new Error(`Page not found: ${slug}`); } return firstPage; }, /** * Fetch a collection of items */ async getCollection(collection, options) { const tag = (0, cache_tags_1.generateCacheTag)('collection', collection, options?.locale); if (config.logging?.queries) { console.log(`[Strapi SDK] getCollection: ${collection}`, { tag, options }); } // Simplified query - real usage will use graphql-codegen const query = ` query GetCollection($locale: String, $filters: JSON, $sort: [String], $pagination: PaginationArg, $publicationState: PublicationState) { ${collection}(locale: $locale, filters: $filters, sort: $sort, pagination: $pagination, publicationState: $publicationState) { data { id attributes } } } `; const variables = buildVariables(options); const data = await client.request(query, variables); const collectionData = data[collection]; return collectionData ? collectionData.data : []; }, /** * Fetch global/singleton data */ async getGlobal(identifier, options) { const tag = (0, cache_tags_1.generateCacheTag)('global', identifier, options?.locale); if (config.logging?.queries) { console.log(`[Strapi SDK] getGlobal: ${identifier}`, { tag, options }); } // Simplified query - real usage will use graphql-codegen const query = ` query GetGlobal($locale: String, $publicationState: PublicationState) { ${identifier}(locale: $locale, publicationState: $publicationState) { data { id attributes } } } `; const variables = buildVariables(options); const data = await client.request(query, variables); const globalData = data[identifier]; if (!globalData) { throw new Error(`Global not found: ${identifier}`); } return globalData.data; }, /** * Execute a raw GraphQL query (escape hatch) */ async rawQuery(query, variables) { if (config.logging?.queries) { console.log('[Strapi SDK] rawQuery', { query, variables }); } return client.request(query, variables); }, }; } exports.createStrapiSDK = createStrapiSDK; //# sourceMappingURL=index.js.map