@intlayer/api 9.0.0-canary.17 → 9.0.0-canary.18

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.
Files changed (142) hide show
  1. package/dist/cjs/cms/createAuthManager.cjs.map +1 -1
  2. package/dist/cjs/cms/createIntlayerCMS.cjs.map +1 -1
  3. package/dist/cjs/distantDictionary/fetchDistantDictionaries.cjs.map +1 -1
  4. package/dist/cjs/distantDictionary/fetchDistantDictionary.cjs.map +1 -1
  5. package/dist/cjs/fetcher.cjs +2 -1
  6. package/dist/cjs/fetcher.cjs.map +1 -1
  7. package/dist/cjs/getIntlayerAPI/ai.cjs.map +1 -1
  8. package/dist/cjs/getIntlayerAPI/analytics.cjs.map +1 -1
  9. package/dist/cjs/getIntlayerAPI/asset.cjs.map +1 -1
  10. package/dist/cjs/getIntlayerAPI/audit.cjs +2 -1
  11. package/dist/cjs/getIntlayerAPI/audit.cjs.map +1 -1
  12. package/dist/cjs/getIntlayerAPI/bitbucket.cjs.map +1 -1
  13. package/dist/cjs/getIntlayerAPI/dictionary.cjs.map +1 -1
  14. package/dist/cjs/getIntlayerAPI/editor.cjs.map +1 -1
  15. package/dist/cjs/getIntlayerAPI/environment.cjs.map +1 -1
  16. package/dist/cjs/getIntlayerAPI/github.cjs.map +1 -1
  17. package/dist/cjs/getIntlayerAPI/gitlab.cjs.map +1 -1
  18. package/dist/cjs/getIntlayerAPI/index.cjs.map +1 -1
  19. package/dist/cjs/getIntlayerAPI/newsletter.cjs.map +1 -1
  20. package/dist/cjs/getIntlayerAPI/oAuth.cjs.map +1 -1
  21. package/dist/cjs/getIntlayerAPI/organization.cjs.map +1 -1
  22. package/dist/cjs/getIntlayerAPI/project.cjs.map +1 -1
  23. package/dist/cjs/getIntlayerAPI/reviewer.cjs.map +1 -1
  24. package/dist/cjs/getIntlayerAPI/search.cjs.map +1 -1
  25. package/dist/cjs/getIntlayerAPI/showcaseProject.cjs.map +1 -1
  26. package/dist/cjs/getIntlayerAPI/status.cjs.map +1 -1
  27. package/dist/cjs/getIntlayerAPI/stripe.cjs +4 -2
  28. package/dist/cjs/getIntlayerAPI/stripe.cjs.map +1 -1
  29. package/dist/cjs/getIntlayerAPI/tag.cjs.map +1 -1
  30. package/dist/cjs/getIntlayerAPI/translate.cjs.map +1 -1
  31. package/dist/cjs/getIntlayerAPI/user.cjs.map +1 -1
  32. package/dist/cjs/proxy.cjs +1 -1
  33. package/dist/cjs/proxy.cjs.map +1 -1
  34. package/dist/esm/cms/createAuthManager.mjs.map +1 -1
  35. package/dist/esm/cms/createIntlayerCMS.mjs.map +1 -1
  36. package/dist/esm/distantDictionary/fetchDistantDictionaries.mjs.map +1 -1
  37. package/dist/esm/distantDictionary/fetchDistantDictionary.mjs.map +1 -1
  38. package/dist/esm/fetcher.mjs +2 -1
  39. package/dist/esm/fetcher.mjs.map +1 -1
  40. package/dist/esm/getIntlayerAPI/ai.mjs.map +1 -1
  41. package/dist/esm/getIntlayerAPI/analytics.mjs.map +1 -1
  42. package/dist/esm/getIntlayerAPI/asset.mjs.map +1 -1
  43. package/dist/esm/getIntlayerAPI/audit.mjs +2 -1
  44. package/dist/esm/getIntlayerAPI/audit.mjs.map +1 -1
  45. package/dist/esm/getIntlayerAPI/bitbucket.mjs.map +1 -1
  46. package/dist/esm/getIntlayerAPI/dictionary.mjs.map +1 -1
  47. package/dist/esm/getIntlayerAPI/editor.mjs.map +1 -1
  48. package/dist/esm/getIntlayerAPI/environment.mjs.map +1 -1
  49. package/dist/esm/getIntlayerAPI/github.mjs.map +1 -1
  50. package/dist/esm/getIntlayerAPI/gitlab.mjs.map +1 -1
  51. package/dist/esm/getIntlayerAPI/index.mjs.map +1 -1
  52. package/dist/esm/getIntlayerAPI/newsletter.mjs.map +1 -1
  53. package/dist/esm/getIntlayerAPI/oAuth.mjs.map +1 -1
  54. package/dist/esm/getIntlayerAPI/organization.mjs.map +1 -1
  55. package/dist/esm/getIntlayerAPI/project.mjs.map +1 -1
  56. package/dist/esm/getIntlayerAPI/reviewer.mjs.map +1 -1
  57. package/dist/esm/getIntlayerAPI/search.mjs.map +1 -1
  58. package/dist/esm/getIntlayerAPI/showcaseProject.mjs.map +1 -1
  59. package/dist/esm/getIntlayerAPI/status.mjs.map +1 -1
  60. package/dist/esm/getIntlayerAPI/stripe.mjs +4 -2
  61. package/dist/esm/getIntlayerAPI/stripe.mjs.map +1 -1
  62. package/dist/esm/getIntlayerAPI/tag.mjs.map +1 -1
  63. package/dist/esm/getIntlayerAPI/translate.mjs.map +1 -1
  64. package/dist/esm/getIntlayerAPI/user.mjs.map +1 -1
  65. package/dist/esm/proxy.mjs +1 -1
  66. package/dist/esm/proxy.mjs.map +1 -1
  67. package/dist/types/{packages/@intlayer → @intlayer}/unmerged-dictionaries-entry/dist/types/index.d.ts +0 -1
  68. package/dist/types/@intlayer/unmerged-dictionaries-entry/dist/types/index.d.ts.map +1 -0
  69. package/dist/types/cms/createAuthManager.d.ts +1 -2
  70. package/dist/types/cms/createAuthManager.d.ts.map +1 -1
  71. package/dist/types/cms/createIntlayerCMS.d.ts +1 -2
  72. package/dist/types/cms/createIntlayerCMS.d.ts.map +1 -1
  73. package/dist/types/distantDictionary/fetchDistantDictionaries.d.ts +0 -1
  74. package/dist/types/distantDictionary/fetchDistantDictionaries.d.ts.map +1 -1
  75. package/dist/types/distantDictionary/fetchDistantDictionary.d.ts +0 -1
  76. package/dist/types/distantDictionary/fetchDistantDictionary.d.ts.map +1 -1
  77. package/dist/types/fetcher.d.ts.map +1 -1
  78. package/dist/types/getIntlayerAPI/ai.d.ts +1 -1
  79. package/dist/types/getIntlayerAPI/ai.d.ts.map +1 -1
  80. package/dist/types/getIntlayerAPI/analytics.d.ts +1 -1
  81. package/dist/types/getIntlayerAPI/analytics.d.ts.map +1 -1
  82. package/dist/types/getIntlayerAPI/asset.d.ts +1 -1
  83. package/dist/types/getIntlayerAPI/asset.d.ts.map +1 -1
  84. package/dist/types/getIntlayerAPI/audit.d.ts +1 -1
  85. package/dist/types/getIntlayerAPI/audit.d.ts.map +1 -1
  86. package/dist/types/getIntlayerAPI/bitbucket.d.ts +1 -1
  87. package/dist/types/getIntlayerAPI/bitbucket.d.ts.map +1 -1
  88. package/dist/types/getIntlayerAPI/dictionary.d.ts +7 -7
  89. package/dist/types/getIntlayerAPI/dictionary.d.ts.map +1 -1
  90. package/dist/types/getIntlayerAPI/editor.d.ts +4 -3
  91. package/dist/types/getIntlayerAPI/editor.d.ts.map +1 -1
  92. package/dist/types/getIntlayerAPI/environment.d.ts +1 -1
  93. package/dist/types/getIntlayerAPI/environment.d.ts.map +1 -1
  94. package/dist/types/getIntlayerAPI/github.d.ts +1 -1
  95. package/dist/types/getIntlayerAPI/github.d.ts.map +1 -1
  96. package/dist/types/getIntlayerAPI/gitlab.d.ts +1 -1
  97. package/dist/types/getIntlayerAPI/gitlab.d.ts.map +1 -1
  98. package/dist/types/getIntlayerAPI/index.d.ts +1 -2
  99. package/dist/types/getIntlayerAPI/index.d.ts.map +1 -1
  100. package/dist/types/getIntlayerAPI/newsletter.d.ts +1 -1
  101. package/dist/types/getIntlayerAPI/newsletter.d.ts.map +1 -1
  102. package/dist/types/getIntlayerAPI/oAuth.d.ts +1 -2
  103. package/dist/types/getIntlayerAPI/oAuth.d.ts.map +1 -1
  104. package/dist/types/getIntlayerAPI/organization.d.ts +5 -5
  105. package/dist/types/getIntlayerAPI/organization.d.ts.map +1 -1
  106. package/dist/types/getIntlayerAPI/project.d.ts +9 -9
  107. package/dist/types/getIntlayerAPI/project.d.ts.map +1 -1
  108. package/dist/types/getIntlayerAPI/reviewer.d.ts +5 -5
  109. package/dist/types/getIntlayerAPI/reviewer.d.ts.map +1 -1
  110. package/dist/types/getIntlayerAPI/search.d.ts +1 -1
  111. package/dist/types/getIntlayerAPI/search.d.ts.map +1 -1
  112. package/dist/types/getIntlayerAPI/showcaseProject.d.ts +7 -7
  113. package/dist/types/getIntlayerAPI/showcaseProject.d.ts.map +1 -1
  114. package/dist/types/getIntlayerAPI/status.d.ts +1 -1
  115. package/dist/types/getIntlayerAPI/status.d.ts.map +1 -1
  116. package/dist/types/getIntlayerAPI/stripe.d.ts +15 -45
  117. package/dist/types/getIntlayerAPI/stripe.d.ts.map +1 -1
  118. package/dist/types/getIntlayerAPI/tag.d.ts +5 -5
  119. package/dist/types/getIntlayerAPI/tag.d.ts.map +1 -1
  120. package/dist/types/getIntlayerAPI/translate.d.ts +1 -1
  121. package/dist/types/getIntlayerAPI/translate.d.ts.map +1 -1
  122. package/dist/types/getIntlayerAPI/user.d.ts +9 -9
  123. package/dist/types/getIntlayerAPI/user.d.ts.map +1 -1
  124. package/dist/types/index.d.ts +3 -1
  125. package/dist/types/{packages/intlayer-editor → intlayer-editor}/server/dist/controllers/configuration.controller.d.ts +1 -3
  126. package/dist/types/intlayer-editor/server/dist/controllers/configuration.controller.d.ts.map +1 -0
  127. package/dist/types/{packages/intlayer-editor → intlayer-editor}/server/dist/controllers/dictionary.controller.d.ts +1 -7
  128. package/dist/types/intlayer-editor/server/dist/controllers/dictionary.controller.d.ts.map +1 -0
  129. package/dist/types/{packages/intlayer-editor → intlayer-editor}/server/dist/export.d.ts +2 -1
  130. package/dist/types/{packages/intlayer-editor → intlayer-editor}/server/dist/utils/httpStatusCodes.d.ts +19 -19
  131. package/dist/types/intlayer-editor/server/dist/utils/httpStatusCodes.d.ts.map +1 -0
  132. package/dist/types/{packages/intlayer-editor → intlayer-editor}/server/dist/utils/responseData.d.ts +0 -1
  133. package/dist/types/intlayer-editor/server/dist/utils/responseData.d.ts.map +1 -0
  134. package/dist/types/proxy.d.ts +1 -2
  135. package/dist/types/proxy.d.ts.map +1 -1
  136. package/dist/types/types.d.ts +1 -1
  137. package/package.json +6 -6
  138. package/dist/types/packages/@intlayer/unmerged-dictionaries-entry/dist/types/index.d.ts.map +0 -1
  139. package/dist/types/packages/intlayer-editor/server/dist/controllers/configuration.controller.d.ts.map +0 -1
  140. package/dist/types/packages/intlayer-editor/server/dist/controllers/dictionary.controller.d.ts.map +0 -1
  141. package/dist/types/packages/intlayer-editor/server/dist/utils/httpStatusCodes.d.ts.map +0 -1
  142. package/dist/types/packages/intlayer-editor/server/dist/utils/responseData.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"createAuthManager.cjs","names":["getOAuthAPI"],"sources":["../../../src/cms/createAuthManager.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { defu } from 'defu';\nimport type { FetcherOptions } from '../fetcher';\nimport { getOAuthAPI } from '../getIntlayerAPI/oAuth';\n\n/**\n * Shape of the various OAuth2 token payloads the backend may return. Only the\n * fields used to derive the expiration timestamp are described here.\n */\ntype OAuthTokenLike = {\n accessToken?: string;\n accessTokenExpiresAt?: string | Date;\n expires_in?: number;\n expiresIn?: number;\n expiresAt?: string | Date;\n};\n\n/**\n * Any asynchronous API method exposed by a domain section\n * (e.g. `getDictionaries`, `pushDictionaries`).\n */\ntype AsyncMethod<Arguments extends unknown[], Result> = (\n ...args: Arguments\n) => Promise<Result>;\n\n/**\n * A domain section factory: builds a plain object of async methods from shared\n * fetcher options and the Intlayer configuration.\n */\ntype SectionFactory<Section extends Record<string, unknown>> = (\n fetcherOptions: FetcherOptions,\n intlayerConfig: IntlayerConfig\n) => Section;\n\nconst ONE_MINUTE_MS = 60_000;\n\n/**\n * Resolves the expiration timestamp (in ms since epoch) from an OAuth2\n * token-like payload, supporting both absolute dates and relative durations.\n */\nconst getExpiryTimestamp = (\n token: OAuthTokenLike | undefined\n): number | undefined => {\n if (!token) return undefined;\n\n const dateLike = (token.accessTokenExpiresAt ?? token.expiresAt) as\n | string\n | Date\n | undefined;\n\n if (dateLike) {\n const timestamp =\n typeof dateLike === 'string'\n ? Date.parse(dateLike)\n : dateLike.getTime?.();\n if (typeof timestamp === 'number' && Number.isFinite(timestamp)) {\n return timestamp;\n }\n }\n\n const seconds = token.expires_in ?? token.expiresIn;\n if (typeof seconds === 'number' && Number.isFinite(seconds)) {\n return Date.now() + seconds * 1000;\n }\n\n return undefined;\n};\n\n/**\n * Options accepted when creating an {@link AuthManager}.\n */\nexport type AuthManagerOptions = {\n /**\n * Base fetcher options merged into every request (e.g. custom headers).\n */\n baseFetcherOptions?: FetcherOptions;\n /**\n * A pre-issued CLI session token (prefixed with `clisession_`). When provided,\n * it is used directly as the Bearer token and the OAuth2 `client_credentials`\n * exchange is skipped entirely.\n */\n sessionToken?: string;\n};\n\n/**\n * Options accepted when binding a domain section to an {@link AuthManager}.\n */\nexport type BindSectionOptions = {\n /**\n * Forces auth injection on (`false`) or off (`true`). Defaults to enabled\n * whenever credentials are available.\n */\n skipAuth?: boolean;\n};\n\n/**\n * Manages CMS authentication for a set of API calls.\n *\n * The manager owns a single mutable {@link FetcherOptions} object\n * (`fetcherOptions`). Domain factories bound through it share the same\n * reference, so refreshing the token in place transparently authenticates every\n * call — without rebuilding the API clients.\n */\nexport type AuthManager = {\n /**\n * Mutable fetcher options carrying the `Authorization` header. Bound sections\n * share this reference so the injected token is reused everywhere.\n */\n fetcherOptions: FetcherOptions;\n /**\n * The resolved Intlayer configuration (merged with the build-time defaults).\n */\n intlayerConfig: IntlayerConfig;\n /**\n * `true` when credentials are available — either a session token or a\n * `clientId`/`clientSecret` pair in the configuration.\n */\n hasCredentials: boolean;\n /**\n * Ensures a valid access token is available and applies it to\n * `fetcherOptions`. Called automatically by {@link withAuth}.\n */\n ensureAuth: () => Promise<void>;\n /**\n * Forces a token refresh on the next call by clearing the cached token.\n */\n reset: () => void;\n /**\n * Wraps a single API method so it injects (and, on failure, refreshes) the\n * access token on every invocation while preserving the method's signature.\n */\n withAuth: <Arguments extends unknown[], Result>(\n method: AsyncMethod<Arguments, Result>,\n skipAuth?: boolean\n ) => AsyncMethod<Arguments, Result>;\n /**\n * Instantiates a domain factory with the managed fetcher options and config,\n * returning a section whose every method authenticates automatically.\n *\n * @example\n * ```ts\n * const dictionary = authManager.bindSection(getDictionaryAPI);\n * await dictionary.pushDictionaries(dictionaries);\n * ```\n */\n bindSection: <Section extends Record<string, unknown>>(\n factory: SectionFactory<Section>,\n options?: BindSectionOptions\n ) => Section;\n};\n\n/**\n * Creates an instance-scoped {@link AuthManager} handling the OAuth2\n * `client_credentials` flow (or a pre-issued CLI session token).\n *\n * Unlike a global token cache, each manager keeps its own token state, so\n * independent SDK instances never interfere with one another.\n *\n * @param intlayerConfig - Intlayer configuration carrying the `editor`\n * credentials. Defaults to the build-time configuration.\n * @param options - Optional session token and base fetcher options.\n */\nexport const createAuthManager = (\n intlayerConfig: Pick<IntlayerConfig, 'editor'> = { editor },\n options: AuthManagerOptions = {}\n): AuthManager => {\n const { baseFetcherOptions = {}, sessionToken } = options;\n\n const resolvedConfig = defu(intlayerConfig ?? {}, {\n editor,\n }) as IntlayerConfig;\n\n // `credentials: 'omit'` prevents the browser from attaching session cookies;\n // authentication is handled exclusively through the injected Bearer token.\n // This is required because the backend only allows credentialed requests for\n // whitelisted first-party origins.\n const fetcherOptions: FetcherOptions = {\n ...baseFetcherOptions,\n credentials: 'omit',\n };\n\n const hasCredentials =\n Boolean(sessionToken) ||\n Boolean(\n resolvedConfig?.editor?.clientId && resolvedConfig?.editor?.clientSecret\n );\n\n // A session token is used as-is and never expires within the SDK's concern,\n // so inject it once up-front and skip the OAuth2 exchange.\n if (sessionToken) {\n fetcherOptions.headers = {\n ...(fetcherOptions.headers ?? {}),\n Authorization: `Bearer ${sessionToken}`,\n } as HeadersInit;\n }\n\n let accessToken: string | undefined;\n let expiryTimestamp: number | undefined;\n let pendingRefresh: Promise<void> | undefined;\n\n const needsRefresh = (): boolean => {\n if (!accessToken) return true;\n if (!expiryTimestamp) return false; // Unknown expiry: assume usable until failure.\n\n // Refresh one minute before the actual expiry to avoid edge-of-expiry races.\n return Date.now() + ONE_MINUTE_MS >= expiryTimestamp;\n };\n\n const refreshToken = async (): Promise<void> => {\n const doRefresh = async (): Promise<void> => {\n const oAuthAPI = getOAuthAPI({}, resolvedConfig);\n const response = await oAuthAPI.getOAuth2AccessToken();\n const tokenData = response?.data as OAuthTokenLike | undefined;\n\n accessToken = tokenData?.accessToken;\n expiryTimestamp = getExpiryTimestamp(tokenData);\n };\n\n // De-duplicate concurrent refreshes so a burst of calls triggers one fetch.\n pendingRefresh ??= doRefresh().finally(() => {\n pendingRefresh = undefined;\n });\n\n await pendingRefresh;\n };\n\n const applyAuthHeader = (): void => {\n if (!accessToken) return;\n fetcherOptions.headers = {\n ...(fetcherOptions.headers ?? {}),\n Authorization: `Bearer ${accessToken}`,\n } as HeadersInit;\n };\n\n const ensureAuth = async (): Promise<void> => {\n if (sessionToken) return; // Already injected; nothing to refresh.\n if (needsRefresh()) {\n await refreshToken();\n }\n applyAuthHeader();\n };\n\n const reset = (): void => {\n accessToken = undefined;\n expiryTimestamp = undefined;\n };\n\n const withAuth = <Arguments extends unknown[], Result>(\n method: AsyncMethod<Arguments, Result>,\n skipAuth = !hasCredentials\n ): AsyncMethod<Arguments, Result> => {\n if (skipAuth) return method;\n\n return async (...args: Arguments): Promise<Result> => {\n await ensureAuth();\n\n try {\n return await method(...args);\n } catch (error) {\n // The token may have been revoked or expired early: refresh once and\n // retry before surfacing the error. A session token cannot be\n // refreshed, so re-throw immediately in that case.\n if (sessionToken) throw error;\n\n await refreshToken();\n applyAuthHeader();\n return await method(...args);\n }\n };\n };\n\n const bindSection = <Section extends Record<string, unknown>>(\n factory: SectionFactory<Section>,\n bindOptions: BindSectionOptions = {}\n ): Section => {\n const section = factory(fetcherOptions, resolvedConfig);\n const skipAuth = bindOptions.skipAuth ?? !hasCredentials;\n\n return new Proxy(section, {\n get(target, property, receiver) {\n const value = Reflect.get(target, property, receiver);\n\n if (typeof value !== 'function') return value;\n\n return withAuth(\n (value as AsyncMethod<unknown[], unknown>).bind(target),\n skipAuth\n );\n },\n });\n };\n\n return {\n fetcherOptions,\n intlayerConfig: resolvedConfig,\n hasCredentials,\n ensureAuth,\n reset,\n withAuth,\n bindSection,\n };\n};\n"],"mappings":";;;;;;AAmCA,MAAM,gBAAgB;;;;;AAMtB,MAAM,sBACJ,UACuB;AACvB,KAAI,CAAC,MAAO,QAAO;CAEnB,MAAM,WAAY,MAAM,wBAAwB,MAAM;AAKtD,KAAI,UAAU;EACZ,MAAM,YACJ,OAAO,aAAa,WAChB,KAAK,MAAM,SAAS,GACpB,SAAS,WAAW;AAC1B,MAAI,OAAO,cAAc,YAAY,OAAO,SAAS,UAAU,CAC7D,QAAO;;CAIX,MAAM,UAAU,MAAM,cAAc,MAAM;AAC1C,KAAI,OAAO,YAAY,YAAY,OAAO,SAAS,QAAQ,CACzD,QAAO,KAAK,KAAK,GAAG,UAAU;;;;;;;;;;;;;AAoGlC,MAAa,qBACX,iBAAiD,EAAE,uCAAQ,EAC3D,UAA8B,EAAE,KAChB;CAChB,MAAM,EAAE,qBAAqB,EAAE,EAAE,iBAAiB;CAElD,MAAM,gCAAsB,kBAAkB,EAAE,EAAE,EAChD,uCACD,CAAC;CAMF,MAAM,iBAAiC;EACrC,GAAG;EACH,aAAa;EACd;CAED,MAAM,iBACJ,QAAQ,aAAa,IACrB,QACE,gBAAgB,QAAQ,YAAY,gBAAgB,QAAQ,aAC7D;AAIH,KAAI,aACF,gBAAe,UAAU;EACvB,GAAI,eAAe,WAAW,EAAE;EAChC,eAAe,UAAU;EAC1B;CAGH,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,MAAM,qBAA8B;AAClC,MAAI,CAAC,YAAa,QAAO;AACzB,MAAI,CAAC,gBAAiB,QAAO;AAG7B,SAAO,KAAK,KAAK,GAAG,iBAAiB;;CAGvC,MAAM,eAAe,YAA2B;EAC9C,MAAM,YAAY,YAA2B;GAG3C,MAAM,aAAY,MAFDA,yCAAY,EAAE,EAAE,eACF,CAAC,sBAAsB,GAC1B;AAE5B,iBAAc,WAAW;AACzB,qBAAkB,mBAAmB,UAAU;;AAIjD,qBAAmB,WAAW,CAAC,cAAc;AAC3C,oBAAiB;IACjB;AAEF,QAAM;;CAGR,MAAM,wBAA8B;AAClC,MAAI,CAAC,YAAa;AAClB,iBAAe,UAAU;GACvB,GAAI,eAAe,WAAW,EAAE;GAChC,eAAe,UAAU;GAC1B;;CAGH,MAAM,aAAa,YAA2B;AAC5C,MAAI,aAAc;AAClB,MAAI,cAAc,CAChB,OAAM,cAAc;AAEtB,mBAAiB;;CAGnB,MAAM,cAAoB;AACxB,gBAAc;AACd,oBAAkB;;CAGpB,MAAM,YACJ,QACA,WAAW,CAAC,mBACuB;AACnC,MAAI,SAAU,QAAO;AAErB,SAAO,OAAO,GAAG,SAAqC;AACpD,SAAM,YAAY;AAElB,OAAI;AACF,WAAO,MAAM,OAAO,GAAG,KAAK;YACrB,OAAO;AAId,QAAI,aAAc,OAAM;AAExB,UAAM,cAAc;AACpB,qBAAiB;AACjB,WAAO,MAAM,OAAO,GAAG,KAAK;;;;CAKlC,MAAM,eACJ,SACA,cAAkC,EAAE,KACxB;EACZ,MAAM,UAAU,QAAQ,gBAAgB,eAAe;EACvD,MAAM,WAAW,YAAY,YAAY,CAAC;AAE1C,SAAO,IAAI,MAAM,SAAS,EACxB,IAAI,QAAQ,UAAU,UAAU;GAC9B,MAAM,QAAQ,QAAQ,IAAI,QAAQ,UAAU,SAAS;AAErD,OAAI,OAAO,UAAU,WAAY,QAAO;AAExC,UAAO,SACJ,MAA0C,KAAK,OAAO,EACvD,SACD;KAEJ,CAAC;;AAGJ,QAAO;EACL;EACA,gBAAgB;EAChB;EACA;EACA;EACA;EACA;EACD"}
1
+ {"version":3,"file":"createAuthManager.cjs","names":["getOAuthAPI"],"sources":["../../../src/cms/createAuthManager.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { defu } from 'defu';\nimport type { FetcherOptions } from '../fetcher';\nimport { getOAuthAPI } from '../getIntlayerAPI/oAuth';\n\n/**\n * Shape of the various OAuth2 token payloads the backend may return. Only the\n * fields used to derive the expiration timestamp are described here.\n */\ntype OAuthTokenLike = {\n accessToken?: string;\n accessTokenExpiresAt?: string | Date;\n expires_in?: number;\n expiresIn?: number;\n expiresAt?: string | Date;\n};\n\n/**\n * Any asynchronous API method exposed by a domain section\n * (e.g. `getDictionaries`, `pushDictionaries`).\n */\ntype AsyncMethod<Arguments extends unknown[], Result> = (\n ...args: Arguments\n) => Promise<Result>;\n\n/**\n * A domain section factory: builds a plain object of async methods from shared\n * fetcher options and the Intlayer configuration.\n */\ntype SectionFactory<Section extends Record<string, unknown>> = (\n fetcherOptions: FetcherOptions,\n intlayerConfig: IntlayerConfig\n) => Section;\n\nconst ONE_MINUTE_MS = 60_000;\n\n/**\n * Resolves the expiration timestamp (in ms since epoch) from an OAuth2\n * token-like payload, supporting both absolute dates and relative durations.\n */\nconst getExpiryTimestamp = (\n token: OAuthTokenLike | undefined\n): number | undefined => {\n if (!token) return undefined;\n\n const dateLike = (token.accessTokenExpiresAt ?? token.expiresAt) as\n | string\n | Date\n | undefined;\n\n if (dateLike) {\n const timestamp =\n typeof dateLike === 'string'\n ? Date.parse(dateLike)\n : dateLike.getTime?.();\n if (typeof timestamp === 'number' && Number.isFinite(timestamp)) {\n return timestamp;\n }\n }\n\n const seconds = token.expires_in ?? token.expiresIn;\n if (typeof seconds === 'number' && Number.isFinite(seconds)) {\n return Date.now() + seconds * 1000;\n }\n\n return undefined;\n};\n\n/**\n * Options accepted when creating an {@link AuthManager}.\n */\nexport type AuthManagerOptions = {\n /**\n * Base fetcher options merged into every request (e.g. custom headers).\n */\n baseFetcherOptions?: FetcherOptions;\n /**\n * A pre-issued CLI session token (prefixed with `clisession_`). When provided,\n * it is used directly as the Bearer token and the OAuth2 `client_credentials`\n * exchange is skipped entirely.\n */\n sessionToken?: string;\n};\n\n/**\n * Options accepted when binding a domain section to an {@link AuthManager}.\n */\nexport type BindSectionOptions = {\n /**\n * Forces auth injection on (`false`) or off (`true`). Defaults to enabled\n * whenever credentials are available.\n */\n skipAuth?: boolean;\n};\n\n/**\n * Manages CMS authentication for a set of API calls.\n *\n * The manager owns a single mutable {@link FetcherOptions} object\n * (`fetcherOptions`). Domain factories bound through it share the same\n * reference, so refreshing the token in place transparently authenticates every\n * call — without rebuilding the API clients.\n */\nexport type AuthManager = {\n /**\n * Mutable fetcher options carrying the `Authorization` header. Bound sections\n * share this reference so the injected token is reused everywhere.\n */\n fetcherOptions: FetcherOptions;\n /**\n * The resolved Intlayer configuration (merged with the build-time defaults).\n */\n intlayerConfig: IntlayerConfig;\n /**\n * `true` when credentials are available — either a session token or a\n * `clientId`/`clientSecret` pair in the configuration.\n */\n hasCredentials: boolean;\n /**\n * Ensures a valid access token is available and applies it to\n * `fetcherOptions`. Called automatically by {@link withAuth}.\n */\n ensureAuth: () => Promise<void>;\n /**\n * Forces a token refresh on the next call by clearing the cached token.\n */\n reset: () => void;\n /**\n * Wraps a single API method so it injects (and, on failure, refreshes) the\n * access token on every invocation while preserving the method's signature.\n */\n withAuth: <Arguments extends unknown[], Result>(\n method: AsyncMethod<Arguments, Result>,\n skipAuth?: boolean\n ) => AsyncMethod<Arguments, Result>;\n /**\n * Instantiates a domain factory with the managed fetcher options and config,\n * returning a section whose every method authenticates automatically.\n *\n * @example\n * ```ts\n * const dictionary = authManager.bindSection(getDictionaryAPI);\n * await dictionary.pushDictionaries(dictionaries);\n * ```\n */\n bindSection: <Section extends Record<string, unknown>>(\n factory: SectionFactory<Section>,\n options?: BindSectionOptions\n ) => Section;\n};\n\n/**\n * Creates an instance-scoped {@link AuthManager} handling the OAuth2\n * `client_credentials` flow (or a pre-issued CLI session token).\n *\n * Unlike a global token cache, each manager keeps its own token state, so\n * independent SDK instances never interfere with one another.\n *\n * @param intlayerConfig - Intlayer configuration carrying the `editor`\n * credentials. Defaults to the build-time configuration.\n * @param options - Optional session token and base fetcher options.\n */\nexport const createAuthManager = (\n intlayerConfig: Pick<IntlayerConfig, 'editor'> = { editor },\n options: AuthManagerOptions = {}\n): AuthManager => {\n const { baseFetcherOptions = {}, sessionToken } = options;\n\n const resolvedConfig = defu(intlayerConfig ?? {}, {\n editor,\n }) as IntlayerConfig;\n\n // `credentials: 'omit'` prevents the browser from attaching session cookies;\n // authentication is handled exclusively through the injected Bearer token.\n // This is required because the backend only allows credentialed requests for\n // whitelisted first-party origins.\n const fetcherOptions: FetcherOptions = {\n ...baseFetcherOptions,\n credentials: 'omit',\n };\n\n const hasCredentials =\n Boolean(sessionToken) ||\n Boolean(\n resolvedConfig?.editor?.clientId && resolvedConfig?.editor?.clientSecret\n );\n\n // A session token is used as-is and never expires within the SDK's concern,\n // so inject it once up-front and skip the OAuth2 exchange.\n if (sessionToken) {\n fetcherOptions.headers = {\n ...(fetcherOptions.headers ?? {}),\n Authorization: `Bearer ${sessionToken}`,\n } as HeadersInit;\n }\n\n let accessToken: string | undefined;\n let expiryTimestamp: number | undefined;\n let pendingRefresh: Promise<void> | undefined;\n\n const needsRefresh = (): boolean => {\n if (!accessToken) return true;\n if (!expiryTimestamp) return false; // Unknown expiry: assume usable until failure.\n\n // Refresh one minute before the actual expiry to avoid edge-of-expiry races.\n return Date.now() + ONE_MINUTE_MS >= expiryTimestamp;\n };\n\n const refreshToken = async (): Promise<void> => {\n const doRefresh = async (): Promise<void> => {\n const oAuthAPI = getOAuthAPI({}, resolvedConfig);\n const response = await oAuthAPI.getOAuth2AccessToken();\n const tokenData = response?.data as OAuthTokenLike | undefined;\n\n accessToken = tokenData?.accessToken;\n expiryTimestamp = getExpiryTimestamp(tokenData);\n };\n\n // De-duplicate concurrent refreshes so a burst of calls triggers one fetch.\n pendingRefresh ??= doRefresh().finally(() => {\n pendingRefresh = undefined;\n });\n\n await pendingRefresh;\n };\n\n const applyAuthHeader = (): void => {\n if (!accessToken) return;\n fetcherOptions.headers = {\n ...(fetcherOptions.headers ?? {}),\n Authorization: `Bearer ${accessToken}`,\n } as HeadersInit;\n };\n\n const ensureAuth = async (): Promise<void> => {\n if (sessionToken) return; // Already injected; nothing to refresh.\n if (needsRefresh()) {\n await refreshToken();\n }\n applyAuthHeader();\n };\n\n const reset = (): void => {\n accessToken = undefined;\n expiryTimestamp = undefined;\n };\n\n const withAuth = <Arguments extends unknown[], Result>(\n method: AsyncMethod<Arguments, Result>,\n skipAuth = !hasCredentials\n ): AsyncMethod<Arguments, Result> => {\n if (skipAuth) return method;\n\n return async (...args: Arguments): Promise<Result> => {\n await ensureAuth();\n\n try {\n return await method(...args);\n } catch (error) {\n // The token may have been revoked or expired early: refresh once and\n // retry before surfacing the error. A session token cannot be\n // refreshed, so re-throw immediately in that case.\n if (sessionToken) throw error;\n\n await refreshToken();\n applyAuthHeader();\n return await method(...args);\n }\n };\n };\n\n const bindSection = <Section extends Record<string, unknown>>(\n factory: SectionFactory<Section>,\n bindOptions: BindSectionOptions = {}\n ): Section => {\n const section = factory(fetcherOptions, resolvedConfig);\n const skipAuth = bindOptions.skipAuth ?? !hasCredentials;\n\n return new Proxy(section, {\n get(target, property, receiver) {\n const value = Reflect.get(target, property, receiver);\n\n if (typeof value !== 'function') return value;\n\n return withAuth(\n (value as AsyncMethod<unknown[], unknown>).bind(target),\n skipAuth\n );\n },\n });\n };\n\n return {\n fetcherOptions,\n intlayerConfig: resolvedConfig,\n hasCredentials,\n ensureAuth,\n reset,\n withAuth,\n bindSection,\n };\n};\n"],"mappings":";;;;;;AAmCA,MAAM,gBAAgB;;;;;AAMtB,MAAM,sBACJ,UACuB;CACvB,IAAI,CAAC,OAAO,OAAO;CAEnB,MAAM,WAAY,MAAM,wBAAwB,MAAM;CAKtD,IAAI,UAAU;EACZ,MAAM,YACJ,OAAO,aAAa,WAChB,KAAK,MAAM,QAAQ,IACnB,SAAS,UAAU;EACzB,IAAI,OAAO,cAAc,YAAY,OAAO,SAAS,SAAS,GAC5D,OAAO;CAEX;CAEA,MAAM,UAAU,MAAM,cAAc,MAAM;CAC1C,IAAI,OAAO,YAAY,YAAY,OAAO,SAAS,OAAO,GACxD,OAAO,KAAK,IAAI,IAAI,UAAU;AAIlC;;;;;;;;;;;;AAgGA,MAAa,qBACX,iBAAiD,EAAE,sCAAO,GAC1D,UAA8B,CAAC,MACf;CAChB,MAAM,EAAE,qBAAqB,CAAC,GAAG,iBAAiB;CAElD,MAAM,gCAAsB,kBAAkB,CAAC,GAAG,EAChD,sCACF,CAAC;CAMD,MAAM,iBAAiC;EACrC,GAAG;EACH,aAAa;CACf;CAEA,MAAM,iBACJ,QAAQ,YAAY,KACpB,QACE,gBAAgB,QAAQ,YAAY,gBAAgB,QAAQ,YAC9D;CAIF,IAAI,cACF,eAAe,UAAU;EACvB,GAAI,eAAe,WAAW,CAAC;EAC/B,eAAe,UAAU;CAC3B;CAGF,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,MAAM,qBAA8B;EAClC,IAAI,CAAC,aAAa,OAAO;EACzB,IAAI,CAAC,iBAAiB,OAAO;EAG7B,OAAO,KAAK,IAAI,IAAI,iBAAiB;CACvC;CAEA,MAAM,eAAe,YAA2B;EAC9C,MAAM,YAAY,YAA2B;GAG3C,MAAM,aAAY,MAFDA,yCAAY,CAAC,GAAG,cACH,CAAC,CAAC,qBAAqB,EAC3B,EAAE;GAE5B,cAAc,WAAW;GACzB,kBAAkB,mBAAmB,SAAS;EAChD;EAGA,mBAAmB,UAAU,CAAC,CAAC,cAAc;GAC3C,iBAAiB;EACnB,CAAC;EAED,MAAM;CACR;CAEA,MAAM,wBAA8B;EAClC,IAAI,CAAC,aAAa;EAClB,eAAe,UAAU;GACvB,GAAI,eAAe,WAAW,CAAC;GAC/B,eAAe,UAAU;EAC3B;CACF;CAEA,MAAM,aAAa,YAA2B;EAC5C,IAAI,cAAc;EAClB,IAAI,aAAa,GACf,MAAM,aAAa;EAErB,gBAAgB;CAClB;CAEA,MAAM,cAAoB;EACxB,cAAc;EACd,kBAAkB;CACpB;CAEA,MAAM,YACJ,QACA,WAAW,CAAC,mBACuB;EACnC,IAAI,UAAU,OAAO;EAErB,OAAO,OAAO,GAAG,SAAqC;GACpD,MAAM,WAAW;GAEjB,IAAI;IACF,OAAO,MAAM,OAAO,GAAG,IAAI;GAC7B,SAAS,OAAO;IAId,IAAI,cAAc,MAAM;IAExB,MAAM,aAAa;IACnB,gBAAgB;IAChB,OAAO,MAAM,OAAO,GAAG,IAAI;GAC7B;EACF;CACF;CAEA,MAAM,eACJ,SACA,cAAkC,CAAC,MACvB;EACZ,MAAM,UAAU,QAAQ,gBAAgB,cAAc;EACtD,MAAM,WAAW,YAAY,YAAY,CAAC;EAE1C,OAAO,IAAI,MAAM,SAAS,EACxB,IAAI,QAAQ,UAAU,UAAU;GAC9B,MAAM,QAAQ,QAAQ,IAAI,QAAQ,UAAU,QAAQ;GAEpD,IAAI,OAAO,UAAU,YAAY,OAAO;GAExC,OAAO,SACJ,MAA0C,KAAK,MAAM,GACtD,QACF;EACF,EACF,CAAC;CACH;CAEA,OAAO;EACL;EACA,gBAAgB;EAChB;EACA;EACA;EACA;EACA;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"createIntlayerCMS.cjs","names":["createAuthManager"],"sources":["../../../src/cms/createIntlayerCMS.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { FetcherOptions } from '../fetcher';\nimport {\n type AuthManager,\n type AuthManagerOptions,\n type BindSectionOptions,\n createAuthManager,\n} from './createAuthManager';\n\n/**\n * Options accepted when creating the Intlayer CMS authenticator.\n */\nexport type IntlayerCMSOptions = AuthManagerOptions;\n\n/**\n * The Intlayer CMS authenticator returned by {@link createIntlayerCMS}.\n *\n * It is a lightweight object that holds the credentials and the managed token,\n * but knows nothing about individual domains. Pair it with a domain endpoint\n * (e.g. `dictionaryEndpoint`) to issue authenticated requests.\n */\nexport type IntlayerCMS = AuthManager;\n\n/**\n * Creates an Intlayer CMS authenticator handling authentication automatically\n * (OAuth2 `client_credentials`, or a CLI session token).\n *\n * This factory is intentionally lightweight: it does **not** bundle any domain\n * client. Combine it with the per-domain endpoint binders — imported separately\n * so only the domains you use are included in your bundle.\n *\n * The configuration is optional: when omitted, the credentials are read from the\n * build-time configuration (`@intlayer/config/built`), which resolves the\n * `INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET` environment variables.\n *\n * > Security: the CMS credentials grant write access to your content. Only ever\n * > create the authenticator on the server side — never ship `clientId` /\n * > `clientSecret` to the browser.\n *\n * @param intlayerConfig - Intlayer configuration carrying the `editor`\n * credentials. Defaults to the build-time configuration.\n * @param options - Optional CLI session token and base fetcher options.\n *\n * @example\n * ```ts\n * import { createIntlayerCMS } from '@intlayer/api';\n * import { dictionaryEndpoint } from '@intlayer/api/dictionary';\n *\n * // Optional: reads INTLAYER_CLIENT_ID / INTLAYER_CLIENT_SECRET when omitted\n * const cms = createIntlayerCMS();\n *\n * // Read\n * const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();\n *\n * // Write\n * await dictionaryEndpoint(cms).pushDictionaries([myDictionary]);\n * ```\n */\nexport const createIntlayerCMS = (\n intlayerConfig: Pick<IntlayerConfig, 'editor'> = { editor },\n options: IntlayerCMSOptions = {}\n): IntlayerCMS => createAuthManager(intlayerConfig, options);\n\n/**\n * A domain endpoint binder: given an authenticator (or none, in which case a\n * default one is created from the build-time configuration), returns the\n * authenticated domain section.\n */\nexport type CMSEndpoint<Section extends Record<string, unknown>> = (\n cms?: IntlayerCMS\n) => Section;\n\n/**\n * Turns a domain factory into a tree-shakeable endpoint binder.\n *\n * Each endpoint pulls in only its own domain client plus the auth machinery, so\n * importing `dictionaryEndpoint` never bundles the project, AI, or any other\n * domain.\n *\n * @param factory - The domain factory (e.g. `getDictionaryAPI`).\n * @param options - Binding options, e.g. `{ skipAuth: true }` for the token\n * endpoint itself.\n *\n * @example\n * ```ts\n * // inside @intlayer/api/dictionary\n * export const dictionaryEndpoint = createEndpoint(getDictionaryAPI);\n * ```\n */\nexport const createEndpoint =\n <Section extends Record<string, unknown>>(\n factory: (\n fetcherOptions: FetcherOptions,\n intlayerConfig: IntlayerConfig\n ) => Section,\n options?: BindSectionOptions\n ): CMSEndpoint<Section> =>\n (cms: IntlayerCMS = createIntlayerCMS()): Section =>\n cms.bindSection(factory, options);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,MAAa,qBACX,iBAAiD,EAAE,uCAAQ,EAC3D,UAA8B,EAAE,KAChBA,gDAAkB,gBAAgB,QAAQ;;;;;;;;;;;;;;;;;;AA4B5D,MAAa,kBAET,SAIA,aAED,MAAmB,mBAAmB,KACrC,IAAI,YAAY,SAAS,QAAQ"}
1
+ {"version":3,"file":"createIntlayerCMS.cjs","names":["createAuthManager"],"sources":["../../../src/cms/createIntlayerCMS.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { FetcherOptions } from '../fetcher';\nimport {\n type AuthManager,\n type AuthManagerOptions,\n type BindSectionOptions,\n createAuthManager,\n} from './createAuthManager';\n\n/**\n * Options accepted when creating the Intlayer CMS authenticator.\n */\nexport type IntlayerCMSOptions = AuthManagerOptions;\n\n/**\n * The Intlayer CMS authenticator returned by {@link createIntlayerCMS}.\n *\n * It is a lightweight object that holds the credentials and the managed token,\n * but knows nothing about individual domains. Pair it with a domain endpoint\n * (e.g. `dictionaryEndpoint`) to issue authenticated requests.\n */\nexport type IntlayerCMS = AuthManager;\n\n/**\n * Creates an Intlayer CMS authenticator handling authentication automatically\n * (OAuth2 `client_credentials`, or a CLI session token).\n *\n * This factory is intentionally lightweight: it does **not** bundle any domain\n * client. Combine it with the per-domain endpoint binders — imported separately\n * so only the domains you use are included in your bundle.\n *\n * The configuration is optional: when omitted, the credentials are read from the\n * build-time configuration (`@intlayer/config/built`), which resolves the\n * `INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET` environment variables.\n *\n * > Security: the CMS credentials grant write access to your content. Only ever\n * > create the authenticator on the server side — never ship `clientId` /\n * > `clientSecret` to the browser.\n *\n * @param intlayerConfig - Intlayer configuration carrying the `editor`\n * credentials. Defaults to the build-time configuration.\n * @param options - Optional CLI session token and base fetcher options.\n *\n * @example\n * ```ts\n * import { createIntlayerCMS } from '@intlayer/api';\n * import { dictionaryEndpoint } from '@intlayer/api/dictionary';\n *\n * // Optional: reads INTLAYER_CLIENT_ID / INTLAYER_CLIENT_SECRET when omitted\n * const cms = createIntlayerCMS();\n *\n * // Read\n * const { data: dictionaries } = await dictionaryEndpoint(cms).getDictionaries();\n *\n * // Write\n * await dictionaryEndpoint(cms).pushDictionaries([myDictionary]);\n * ```\n */\nexport const createIntlayerCMS = (\n intlayerConfig: Pick<IntlayerConfig, 'editor'> = { editor },\n options: IntlayerCMSOptions = {}\n): IntlayerCMS => createAuthManager(intlayerConfig, options);\n\n/**\n * A domain endpoint binder: given an authenticator (or none, in which case a\n * default one is created from the build-time configuration), returns the\n * authenticated domain section.\n */\nexport type CMSEndpoint<Section extends Record<string, unknown>> = (\n cms?: IntlayerCMS\n) => Section;\n\n/**\n * Turns a domain factory into a tree-shakeable endpoint binder.\n *\n * Each endpoint pulls in only its own domain client plus the auth machinery, so\n * importing `dictionaryEndpoint` never bundles the project, AI, or any other\n * domain.\n *\n * @param factory - The domain factory (e.g. `getDictionaryAPI`).\n * @param options - Binding options, e.g. `{ skipAuth: true }` for the token\n * endpoint itself.\n *\n * @example\n * ```ts\n * // inside @intlayer/api/dictionary\n * export const dictionaryEndpoint = createEndpoint(getDictionaryAPI);\n * ```\n */\nexport const createEndpoint =\n <Section extends Record<string, unknown>>(\n factory: (\n fetcherOptions: FetcherOptions,\n intlayerConfig: IntlayerConfig\n ) => Section,\n options?: BindSectionOptions\n ): CMSEndpoint<Section> =>\n (cms: IntlayerCMS = createIntlayerCMS()): Section =>\n cms.bindSection(factory, options);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,MAAa,qBACX,iBAAiD,EAAE,sCAAO,GAC1D,UAA8B,CAAC,MACfA,gDAAkB,gBAAgB,OAAO;;;;;;;;;;;;;;;;;;AA4B3D,MAAa,kBAET,SAIA,aAED,MAAmB,kBAAkB,MACpC,IAAI,YAAY,SAAS,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetchDistantDictionaries.cjs","names":["dictionaryEndpoint","createIntlayerCMS"],"sources":["../../../src/distantDictionary/fetchDistantDictionaries.ts"],"sourcesContent":["import type { DictionaryAPI } from '@intlayer/backend';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createIntlayerCMS } from '../cms/createIntlayerCMS';\nimport { dictionaryEndpoint } from '../getIntlayerAPI/dictionary';\n\n/**\n * Fetch distant dictionary\n */\nexport const fetchDistantDictionaries = async (\n intlayerConfig: IntlayerConfig\n): Promise<DictionaryAPI[] | null | undefined> => {\n try {\n const { clientId, clientSecret } = intlayerConfig.editor;\n\n if (!clientId || !clientSecret) {\n throw new Error(\n 'Missing OAuth2 client ID or client secret. To get access token go to https://app.intlayer.org/project.'\n );\n }\n\n const dictionary = dictionaryEndpoint(createIntlayerCMS(intlayerConfig));\n\n // Fetch the dictionary list\n const getDictionaryResult = await dictionary.getDictionaries();\n\n const distantDictionaries = getDictionaryResult.data;\n\n return distantDictionaries;\n } catch (error) {\n console.error(error);\n return undefined;\n }\n};\n"],"mappings":";;;;;;;;AAQA,MAAa,2BAA2B,OACtC,mBACgD;AAChD,KAAI;EACF,MAAM,EAAE,UAAU,iBAAiB,eAAe;AAElD,MAAI,CAAC,YAAY,CAAC,aAChB,OAAM,IAAI,MACR,yGACD;AAUH,UAF4B,MALTA,qDAAmBC,gDAAkB,eAAe,CAG3B,CAAC,iBAAiB,EAEd;UAGzC,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB"}
1
+ {"version":3,"file":"fetchDistantDictionaries.cjs","names":["dictionaryEndpoint","createIntlayerCMS"],"sources":["../../../src/distantDictionary/fetchDistantDictionaries.ts"],"sourcesContent":["import type { DictionaryAPI } from '@intlayer/backend';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createIntlayerCMS } from '../cms/createIntlayerCMS';\nimport { dictionaryEndpoint } from '../getIntlayerAPI/dictionary';\n\n/**\n * Fetch distant dictionary\n */\nexport const fetchDistantDictionaries = async (\n intlayerConfig: IntlayerConfig\n): Promise<DictionaryAPI[] | null | undefined> => {\n try {\n const { clientId, clientSecret } = intlayerConfig.editor;\n\n if (!clientId || !clientSecret) {\n throw new Error(\n 'Missing OAuth2 client ID or client secret. To get access token go to https://app.intlayer.org/project.'\n );\n }\n\n const dictionary = dictionaryEndpoint(createIntlayerCMS(intlayerConfig));\n\n // Fetch the dictionary list\n const getDictionaryResult = await dictionary.getDictionaries();\n\n const distantDictionaries = getDictionaryResult.data;\n\n return distantDictionaries;\n } catch (error) {\n console.error(error);\n return undefined;\n }\n};\n"],"mappings":";;;;;;;;AAQA,MAAa,2BAA2B,OACtC,mBACgD;CAChD,IAAI;EACF,MAAM,EAAE,UAAU,iBAAiB,eAAe;EAElD,IAAI,CAAC,YAAY,CAAC,cAChB,MAAM,IAAI,MACR,wGACF;EAUF,QAF4B,MALTA,qDAAmBC,gDAAkB,cAAc,CAG3B,CAAC,CAAC,gBAAgB,EAEd,CAAC;CAGlD,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;EACnB;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetchDistantDictionary.cjs","names":["dictionaryEndpoint","createIntlayerCMS"],"sources":["../../../src/distantDictionary/fetchDistantDictionary.ts"],"sourcesContent":["import type { DictionaryAPI } from '@intlayer/backend';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createIntlayerCMS } from '../cms/createIntlayerCMS';\nimport { dictionaryEndpoint } from '../getIntlayerAPI/dictionary';\n\n/**\n * Fetch distant dictionary\n */\nexport const fetchDistantDictionary = async (\n dictionaryKey: string,\n intlayerConfig: IntlayerConfig\n): Promise<DictionaryAPI | undefined> => {\n try {\n const { clientId, clientSecret } = intlayerConfig.editor;\n\n if (!clientId || !clientSecret) {\n throw new Error(\n 'Missing OAuth2 client ID or client secret. To get access token go to https://app.intlayer.org/project.'\n );\n }\n\n const dictionary = dictionaryEndpoint(createIntlayerCMS(intlayerConfig));\n\n // Fetch the dictionary\n const getDictionaryResult = await dictionary.getDictionary(dictionaryKey);\n\n const distantDictionary = getDictionaryResult.data;\n\n if (!distantDictionary) {\n throw new Error(`Dictionary ${dictionaryKey} not found on remote`);\n }\n\n return distantDictionary;\n } catch (error) {\n console.error(error);\n return undefined;\n }\n};\n"],"mappings":";;;;;;;;AAQA,MAAa,yBAAyB,OACpC,eACA,mBACuC;AACvC,KAAI;EACF,MAAM,EAAE,UAAU,iBAAiB,eAAe;AAElD,MAAI,CAAC,YAAY,CAAC,aAChB,OAAM,IAAI,MACR,yGACD;EAQH,MAAM,qBAAoB,MALPA,qDAAmBC,gDAAkB,eAAe,CAG3B,CAAC,cAAc,cAAc,EAE3B;AAE9C,MAAI,CAAC,kBACH,OAAM,IAAI,MAAM,cAAc,cAAc,sBAAsB;AAGpE,SAAO;UACA,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB"}
1
+ {"version":3,"file":"fetchDistantDictionary.cjs","names":["dictionaryEndpoint","createIntlayerCMS"],"sources":["../../../src/distantDictionary/fetchDistantDictionary.ts"],"sourcesContent":["import type { DictionaryAPI } from '@intlayer/backend';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createIntlayerCMS } from '../cms/createIntlayerCMS';\nimport { dictionaryEndpoint } from '../getIntlayerAPI/dictionary';\n\n/**\n * Fetch distant dictionary\n */\nexport const fetchDistantDictionary = async (\n dictionaryKey: string,\n intlayerConfig: IntlayerConfig\n): Promise<DictionaryAPI | undefined> => {\n try {\n const { clientId, clientSecret } = intlayerConfig.editor;\n\n if (!clientId || !clientSecret) {\n throw new Error(\n 'Missing OAuth2 client ID or client secret. To get access token go to https://app.intlayer.org/project.'\n );\n }\n\n const dictionary = dictionaryEndpoint(createIntlayerCMS(intlayerConfig));\n\n // Fetch the dictionary\n const getDictionaryResult = await dictionary.getDictionary(dictionaryKey);\n\n const distantDictionary = getDictionaryResult.data;\n\n if (!distantDictionary) {\n throw new Error(`Dictionary ${dictionaryKey} not found on remote`);\n }\n\n return distantDictionary;\n } catch (error) {\n console.error(error);\n return undefined;\n }\n};\n"],"mappings":";;;;;;;;AAQA,MAAa,yBAAyB,OACpC,eACA,mBACuC;CACvC,IAAI;EACF,MAAM,EAAE,UAAU,iBAAiB,eAAe;EAElD,IAAI,CAAC,YAAY,CAAC,cAChB,MAAM,IAAI,MACR,wGACF;EAQF,MAAM,qBAAoB,MALPA,qDAAmBC,gDAAkB,cAAc,CAG3B,CAAC,CAAC,cAAc,aAAa,EAE3B,CAAC;EAE9C,IAAI,CAAC,mBACH,MAAM,IAAI,MAAM,cAAc,cAAc,qBAAqB;EAGnE,OAAO;CACT,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;EACnB;CACF;AACF"}
@@ -92,7 +92,8 @@ const fetcher = async (url, ...options) => {
92
92
  const { signal } = new AbortController();
93
93
  let paramsString = "";
94
94
  let bodyString;
95
- const mergedOptions = deepMerge([fetcherOptions, ...options.map(({ body, params, headers, ...otherOptions }) => otherOptions)]);
95
+ const otherOptions = options.map(({ body, params, headers, ...otherOptions }) => otherOptions);
96
+ const mergedOptions = deepMerge([fetcherOptions, ...otherOptions]);
96
97
  const mergedHeaders = deepMerge([fetcherOptions.headers, ...options.map((option) => option.headers)]);
97
98
  const params = deepMerge(options.map((option) => option.params));
98
99
  const method = mergedOptions.method;
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.cjs","names":[],"sources":["../../src/fetcher.ts"],"sourcesContent":["/**\n * Type definition for options used in the fetcher function.\n * Extends the standard RequestInit interface (excluding 'body'),\n * and adds 'body' and 'params' properties for convenience.\n */\nexport type FetcherOptions = Omit<RequestInit, 'body'> & {\n /**\n * Body of the request. Should be a key-value pair object.\n */\n body?: Record<string, unknown>;\n /**\n * Query parameters to be appended to the URL.\n */\n params?:\n | Record<string, string | string[] | undefined>\n | string[]\n | URLSearchParams;\n};\n\n/**\n * Default options for the fetcher function.\n * Sets the default method to 'GET', the 'Content-Type' header to 'application/json',\n * and includes credentials in the request.\n */\nexport const fetcherOptions: FetcherOptions = {\n method: 'GET', // Default HTTP method\n headers: {\n 'Content-Type': 'application/json', // Default content type\n },\n credentials: 'include',\n};\n\n/**\n * Utility function to remove properties with undefined values from an object.\n * This helps prevent sending undefined values in the request options.\n *\n * @param obj - The object to clean.\n * @returns The cleaned object without undefined values.\n */\nconst removeUndefined = (obj: object) => {\n Object.keys(obj).forEach((key) => {\n if (obj[key as keyof typeof obj] === undefined) {\n delete obj[key as keyof typeof obj];\n }\n });\n return obj;\n};\n\n/**\n * Deeply merges an array of objects into a single object.\n * Later objects in the array overwrite properties of earlier ones.\n *\n * @template T - The type of objects being merged.\n * @param objects - An array of objects to merge.\n * @returns The merged object.\n */\nconst deepMerge = <T extends object>(objects: (T | undefined)[]): T =>\n objects.reduce((acc, obj) => {\n const acc1: T = (acc ?? {}) as T;\n const obj1: T = removeUndefined(obj ?? {}) as T;\n\n if (typeof acc1 === 'object' && typeof obj1 === 'object') {\n // Merge the two objects\n return { ...acc1, ...obj1 };\n }\n\n // If one of them is not an object, return the defined one\n return obj1 ?? acc1;\n }, {} as T)!;\n\n/**\n * Fetcher function to make HTTP requests.\n * It merges default options with user-provided options,\n * handles query parameters and request body,\n * and returns the parsed JSON response.\n *\n * @template T - The expected type of the response data.\n * @param url - The endpoint URL.\n * @param options - Additional options to customize the request.\n * @returns A promise that resolves with the response data of type T.\n *\n * @example\n * ```typescript\n * // Making a GET request with query parameters\n * const data = await fetcher<MyResponseType>('https://api.example.com/data', {\n * params: { search: 'query' },\n * });\n *\n * // Making a POST request with a JSON body\n * const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {\n * method: 'POST',\n * body: { key: 'value' },\n * });\n *\n * // Merge body, headers, and params\n * const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {\n * method: 'POST',\n * body: { key: 'value' },\n * headers: { 'Content-Type': 'application/json' },\n * params: { search: 'query' },\n * },\n * {\n * headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n * params: { page: 1 },\n * });\n * ```\n *\n * Result:\n * ```typescript\n * {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n * params: { page: 1, search: 'query' },\n * body: { key: 'value' },\n * }\n * ```\n */\nexport const fetcher = async <T>(\n url: string,\n ...options: FetcherOptions[]\n): Promise<T> => {\n const { signal } = new AbortController();\n\n // Initialize query parameters string and request body string\n let paramsString = '';\n let bodyString: string | undefined;\n\n // Extract other options excluding 'body', 'params', and 'headers'\n const otherOptions = options.map(\n ({ body, params, headers, ...otherOptions }) => otherOptions\n );\n\n // Merge default options with user-provided options\n const mergedOptions = deepMerge([fetcherOptions, ...otherOptions]);\n\n // Merge default headers with user-provided headers\n const mergedHeaders = deepMerge([\n fetcherOptions.headers,\n ...options.map((option) => option.headers),\n ]);\n\n // Merge query parameters\n const params = deepMerge(options.map((option) => option.params));\n\n const method = mergedOptions.method;\n\n // If the request method is not 'GET' or 'HEAD', prepare the request body\n if (method !== 'GET' && method !== 'HEAD') {\n // Merge all 'body' options\n const body = deepMerge(options.map((option) => option.body));\n if (\n mergedHeaders?.['Content-Type' as keyof HeadersInit] ===\n 'application/x-www-form-urlencoded'\n ) {\n // If the content type is 'application/x-www-form-urlencoded', encode the body accordingly\n bodyString = new URLSearchParams(\n body as Record<string, string>\n ).toString();\n } else {\n // Otherwise, stringify the body as JSON\n bodyString = JSON.stringify(body);\n }\n }\n\n // If there are query parameters, append them to the URL\n if (Object.entries(params).length > 0) {\n paramsString = `?${new URLSearchParams(\n params as Record<string, string>\n ).toString()}`;\n }\n\n // Prepare the final request options\n const formattedOptions: RequestInit = {\n ...mergedOptions,\n headers: mergedHeaders,\n body: bodyString,\n signal,\n };\n\n // Construct the full URL with query parameters\n const urlResult = `${url}${paramsString}`;\n\n // Make the HTTP request using fetch\n const response = await fetch(urlResult, formattedOptions);\n\n if (!response.ok) {\n const result = await response.json();\n\n // You can customize the error message or include more details\n throw new Error(JSON.stringify(result.error) ?? 'An error occurred');\n }\n return await response.json();\n};\n"],"mappings":";;;;;;;;AAwBA,MAAa,iBAAiC;CAC5C,QAAQ;CACR,SAAS,EACP,gBAAgB,oBACjB;CACD,aAAa;CACd;;;;;;;;AASD,MAAM,mBAAmB,QAAgB;AACvC,QAAO,KAAK,IAAI,CAAC,SAAS,QAAQ;AAChC,MAAI,IAAI,SAA6B,OACnC,QAAO,IAAI;GAEb;AACF,QAAO;;;;;;;;;;AAWT,MAAM,aAA+B,YACnC,QAAQ,QAAQ,KAAK,QAAQ;CAC3B,MAAM,OAAW,OAAO,EAAE;CAC1B,MAAM,OAAU,gBAAgB,OAAO,EAAE,CAAC;AAE1C,KAAI,OAAO,SAAS,YAAY,OAAO,SAAS,SAE9C,QAAO;EAAE,GAAG;EAAM,GAAG;EAAM;AAI7B,QAAO,QAAQ;GACd,EAAE,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDb,MAAa,UAAU,OACrB,KACA,GAAG,YACY;CACf,MAAM,EAAE,WAAW,IAAI,iBAAiB;CAGxC,IAAI,eAAe;CACnB,IAAI;CAQJ,MAAM,gBAAgB,UAAU,CAAC,gBAAgB,GAL5B,QAAQ,KAC1B,EAAE,MAAM,QAAQ,SAAS,GAAG,mBAAmB,aAIc,CAAC,CAAC;CAGlE,MAAM,gBAAgB,UAAU,CAC9B,eAAe,SACf,GAAG,QAAQ,KAAK,WAAW,OAAO,QAAQ,CAC3C,CAAC;CAGF,MAAM,SAAS,UAAU,QAAQ,KAAK,WAAW,OAAO,OAAO,CAAC;CAEhE,MAAM,SAAS,cAAc;AAG7B,KAAI,WAAW,SAAS,WAAW,QAAQ;EAEzC,MAAM,OAAO,UAAU,QAAQ,KAAK,WAAW,OAAO,KAAK,CAAC;AAC5D,MACE,gBAAgB,oBAChB,oCAGA,cAAa,IAAI,gBACf,KACD,CAAC,UAAU;MAGZ,cAAa,KAAK,UAAU,KAAK;;AAKrC,KAAI,OAAO,QAAQ,OAAO,CAAC,SAAS,EAClC,gBAAe,IAAI,IAAI,gBACrB,OACD,CAAC,UAAU;CAId,MAAM,mBAAgC;EACpC,GAAG;EACH,SAAS;EACT,MAAM;EACN;EACD;CAGD,MAAM,YAAY,GAAG,MAAM;CAG3B,MAAM,WAAW,MAAM,MAAM,WAAW,iBAAiB;AAEzD,KAAI,CAAC,SAAS,IAAI;EAChB,MAAM,SAAS,MAAM,SAAS,MAAM;AAGpC,QAAM,IAAI,MAAM,KAAK,UAAU,OAAO,MAAM,IAAI,oBAAoB;;AAEtE,QAAO,MAAM,SAAS,MAAM"}
1
+ {"version":3,"file":"fetcher.cjs","names":[],"sources":["../../src/fetcher.ts"],"sourcesContent":["/**\n * Type definition for options used in the fetcher function.\n * Extends the standard RequestInit interface (excluding 'body'),\n * and adds 'body' and 'params' properties for convenience.\n */\nexport type FetcherOptions = Omit<RequestInit, 'body'> & {\n /**\n * Body of the request. Should be a key-value pair object.\n */\n body?: Record<string, unknown>;\n /**\n * Query parameters to be appended to the URL.\n */\n params?:\n | Record<string, string | string[] | undefined>\n | string[]\n | URLSearchParams;\n};\n\n/**\n * Default options for the fetcher function.\n * Sets the default method to 'GET', the 'Content-Type' header to 'application/json',\n * and includes credentials in the request.\n */\nexport const fetcherOptions: FetcherOptions = {\n method: 'GET', // Default HTTP method\n headers: {\n 'Content-Type': 'application/json', // Default content type\n },\n credentials: 'include',\n};\n\n/**\n * Utility function to remove properties with undefined values from an object.\n * This helps prevent sending undefined values in the request options.\n *\n * @param obj - The object to clean.\n * @returns The cleaned object without undefined values.\n */\nconst removeUndefined = (obj: object) => {\n Object.keys(obj).forEach((key) => {\n if (obj[key as keyof typeof obj] === undefined) {\n delete obj[key as keyof typeof obj];\n }\n });\n return obj;\n};\n\n/**\n * Deeply merges an array of objects into a single object.\n * Later objects in the array overwrite properties of earlier ones.\n *\n * @template T - The type of objects being merged.\n * @param objects - An array of objects to merge.\n * @returns The merged object.\n */\nconst deepMerge = <T extends object>(objects: (T | undefined)[]): T =>\n objects.reduce((acc, obj) => {\n const acc1: T = (acc ?? {}) as T;\n const obj1: T = removeUndefined(obj ?? {}) as T;\n\n if (typeof acc1 === 'object' && typeof obj1 === 'object') {\n // Merge the two objects\n return { ...acc1, ...obj1 };\n }\n\n // If one of them is not an object, return the defined one\n return obj1 ?? acc1;\n }, {} as T)!;\n\n/**\n * Fetcher function to make HTTP requests.\n * It merges default options with user-provided options,\n * handles query parameters and request body,\n * and returns the parsed JSON response.\n *\n * @template T - The expected type of the response data.\n * @param url - The endpoint URL.\n * @param options - Additional options to customize the request.\n * @returns A promise that resolves with the response data of type T.\n *\n * @example\n * ```typescript\n * // Making a GET request with query parameters\n * const data = await fetcher<MyResponseType>('https://api.example.com/data', {\n * params: { search: 'query' },\n * });\n *\n * // Making a POST request with a JSON body\n * const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {\n * method: 'POST',\n * body: { key: 'value' },\n * });\n *\n * // Merge body, headers, and params\n * const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {\n * method: 'POST',\n * body: { key: 'value' },\n * headers: { 'Content-Type': 'application/json' },\n * params: { search: 'query' },\n * },\n * {\n * headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n * params: { page: 1 },\n * });\n * ```\n *\n * Result:\n * ```typescript\n * {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n * params: { page: 1, search: 'query' },\n * body: { key: 'value' },\n * }\n * ```\n */\nexport const fetcher = async <T>(\n url: string,\n ...options: FetcherOptions[]\n): Promise<T> => {\n const { signal } = new AbortController();\n\n // Initialize query parameters string and request body string\n let paramsString = '';\n let bodyString: string | undefined;\n\n // Extract other options excluding 'body', 'params', and 'headers'\n const otherOptions = options.map(\n ({ body, params, headers, ...otherOptions }) => otherOptions\n );\n\n // Merge default options with user-provided options\n const mergedOptions = deepMerge([fetcherOptions, ...otherOptions]);\n\n // Merge default headers with user-provided headers\n const mergedHeaders = deepMerge([\n fetcherOptions.headers,\n ...options.map((option) => option.headers),\n ]);\n\n // Merge query parameters\n const params = deepMerge(options.map((option) => option.params));\n\n const method = mergedOptions.method;\n\n // If the request method is not 'GET' or 'HEAD', prepare the request body\n if (method !== 'GET' && method !== 'HEAD') {\n // Merge all 'body' options\n const body = deepMerge(options.map((option) => option.body));\n if (\n mergedHeaders?.['Content-Type' as keyof HeadersInit] ===\n 'application/x-www-form-urlencoded'\n ) {\n // If the content type is 'application/x-www-form-urlencoded', encode the body accordingly\n bodyString = new URLSearchParams(\n body as Record<string, string>\n ).toString();\n } else {\n // Otherwise, stringify the body as JSON\n bodyString = JSON.stringify(body);\n }\n }\n\n // If there are query parameters, append them to the URL\n if (Object.entries(params).length > 0) {\n paramsString = `?${new URLSearchParams(\n params as Record<string, string>\n ).toString()}`;\n }\n\n // Prepare the final request options\n const formattedOptions: RequestInit = {\n ...mergedOptions,\n headers: mergedHeaders,\n body: bodyString,\n signal,\n };\n\n // Construct the full URL with query parameters\n const urlResult = `${url}${paramsString}`;\n\n // Make the HTTP request using fetch\n const response = await fetch(urlResult, formattedOptions);\n\n if (!response.ok) {\n const result = await response.json();\n\n // You can customize the error message or include more details\n throw new Error(JSON.stringify(result.error) ?? 'An error occurred');\n }\n return await response.json();\n};\n"],"mappings":";;;;;;;;AAwBA,MAAa,iBAAiC;CAC5C,QAAQ;CACR,SAAS,EACP,gBAAgB,mBAClB;CACA,aAAa;AACf;;;;;;;;AASA,MAAM,mBAAmB,QAAgB;CACvC,OAAO,KAAK,GAAG,CAAC,CAAC,SAAS,QAAQ;EAChC,IAAI,IAAI,SAA6B,QACnC,OAAO,IAAI;CAEf,CAAC;CACD,OAAO;AACT;;;;;;;;;AAUA,MAAM,aAA+B,YACnC,QAAQ,QAAQ,KAAK,QAAQ;CAC3B,MAAM,OAAW,OAAO,CAAC;CACzB,MAAM,OAAU,gBAAgB,OAAO,CAAC,CAAC;CAEzC,IAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAE9C,OAAO;EAAE,GAAG;EAAM,GAAG;CAAK;CAI5B,OAAO,QAAQ;AACjB,GAAG,CAAC,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDZ,MAAa,UAAU,OACrB,KACA,GAAG,YACY;CACf,MAAM,EAAE,WAAW,IAAI,gBAAgB;CAGvC,IAAI,eAAe;CACnB,IAAI;CAGJ,MAAM,eAAe,QAAQ,KAC1B,EAAE,MAAM,QAAQ,SAAS,GAAG,mBAAmB,YAClD;CAGA,MAAM,gBAAgB,UAAU,CAAC,gBAAgB,GAAG,YAAY,CAAC;CAGjE,MAAM,gBAAgB,UAAU,CAC9B,eAAe,SACf,GAAG,QAAQ,KAAK,WAAW,OAAO,OAAO,CAC3C,CAAC;CAGD,MAAM,SAAS,UAAU,QAAQ,KAAK,WAAW,OAAO,MAAM,CAAC;CAE/D,MAAM,SAAS,cAAc;CAG7B,IAAI,WAAW,SAAS,WAAW,QAAQ;EAEzC,MAAM,OAAO,UAAU,QAAQ,KAAK,WAAW,OAAO,IAAI,CAAC;EAC3D,IACE,gBAAgB,oBAChB,qCAGA,aAAa,IAAI,gBACf,IACF,CAAC,CAAC,SAAS;OAGX,aAAa,KAAK,UAAU,IAAI;CAEpC;CAGA,IAAI,OAAO,QAAQ,MAAM,CAAC,CAAC,SAAS,GAClC,eAAe,IAAI,IAAI,gBACrB,MACF,CAAC,CAAC,SAAS;CAIb,MAAM,mBAAgC;EACpC,GAAG;EACH,SAAS;EACT,MAAM;EACN;CACF;CAGA,MAAM,YAAY,GAAG,MAAM;CAG3B,MAAM,WAAW,MAAM,MAAM,WAAW,gBAAgB;CAExD,IAAI,CAAC,SAAS,IAAI;EAChB,MAAM,SAAS,MAAM,SAAS,KAAK;EAGnC,MAAM,IAAI,MAAM,KAAK,UAAU,OAAO,KAAK,KAAK,mBAAmB;CACrE;CACA,OAAO,MAAM,SAAS,KAAK;AAC7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"ai.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/ai.ts"],"sourcesContent":["import type {\n AIOptions,\n AskDocQuestionResult,\n AuditContentDeclarationBody,\n AuditContentDeclarationFieldBody,\n AuditContentDeclarationFieldResult,\n AuditContentDeclarationMetadataBody,\n AuditContentDeclarationMetadataResult,\n AuditContentDeclarationResult,\n AuditTagBody,\n AuditTagResult,\n AutocompleteResponse,\n ChatCompletionRequestMessage,\n ChatResult,\n CustomQueryBody,\n CustomQueryResult,\n GetAIStatsResult,\n GetDiscussionsParams,\n GetDiscussionsResult,\n TranslateJSONBody,\n TranslateJSONResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type AutocompleteBody = {\n text: string;\n aiOptions?: AIOptions;\n contextBefore?: string;\n currentLine?: string;\n contextAfter?: string;\n};\n\nexport type AskDocQuestionBody = {\n messages: ChatCompletionRequestMessage[];\n discussionId: string;\n onMessage?: (chunk: string) => void;\n onDone?: (response: AskDocQuestionResult) => void;\n};\n\nexport type ClientAction =\n | { type: 'navigate'; path: string }\n | { type: 'invalidate_queries' };\n\nexport type ChatBody = {\n messages: ChatCompletionRequestMessage[];\n discussionId: string;\n onMessage?: (chunk: string) => void;\n onDone?: (response: ChatResult) => void;\n onAction?: (action: ClientAction) => void;\n};\n\nexport type { AskDocQuestionResult, ChatResult };\n\nexport const getAiAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const AI_API_ROUTE = `${backendURL}/api/ai`;\n\n /**\n * Custom query\n * @param body - Custom query parameters.\n * @returns Custom query result.\n */\n const customQuery = async (\n body?: CustomQueryBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<CustomQueryResult>(\n AI_API_ROUTE,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Translate a JSON\n * @param body - Audit file parameters.\n * @returns Audited file content.\n */\n const translateJSON = async (\n body?: TranslateJSONBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<TranslateJSONResult>(\n `${AI_API_ROUTE}/translate/json`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Audits a content declaration file\n * @param body - Audit file parameters.\n * @returns Audited file content.\n */\n const auditContentDeclaration = async (\n body?: AuditContentDeclarationBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AuditContentDeclarationResult>(\n `${AI_API_ROUTE}/audit/dictionary`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Audits a content declaration field\n * @param body - Audit file parameters.\n * @returns Audited file content.\n */\n const auditContentDeclarationField = async (\n body?: AuditContentDeclarationFieldBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AuditContentDeclarationFieldResult>(\n `${AI_API_ROUTE}/audit/dictionary/field`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Audits a content declaration file to retrieve title, description and tags\n * @param body - Audit file parameters.\n * @returns Audited file content.\n */\n const auditContentDeclarationMetadata = async (\n body?: AuditContentDeclarationMetadataBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AuditContentDeclarationMetadataResult>(\n `${AI_API_ROUTE}/audit/dictionary/metadata`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Audits a tag\n * @param body - Audit tag parameters.\n * @returns Audited tag content.\n */\n const auditTag = async (\n body?: AuditTagBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AuditTagResult>(\n `${AI_API_ROUTE}/audit/tag`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Asks a question to the AI related to the documentation **and streams the\n * answer as Server‑Sent Events (SSE)**.\n *\n * The function **returns immediately** with a handle exposing:\n * - `promise` → resolves when the stream completes (or rejects on error)\n * - `abort()` → allows canceling the request on demand\n *\n * Usage example:\n * ```ts\n * const { promise, abort } = ai.askDocQuestion({\n * ...body,\n * onMessage: console.log,\n * onDone: (full) => console.log(\"✔\", full),\n * });\n * // later → abort();\n * await promise; // waits for completion if desired\n * ```\n */\n const askDocQuestion = async (\n body?: AskDocQuestionBody,\n otherOptions: FetcherOptions = {}\n ) => {\n if (!body) return;\n\n const { onMessage, onDone, ...rest } = body;\n const abortController = new AbortController();\n\n try {\n const response = await fetch(`${AI_API_ROUTE}/ask`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authAPIOptions.headers,\n ...otherOptions.headers,\n },\n body: JSON.stringify({\n ...rest,\n ...authAPIOptions.body,\n ...otherOptions.body,\n }),\n signal: abortController.signal,\n credentials: 'include',\n });\n\n if (!response.ok) {\n // Align error handling with generic `fetcher` utility so that callers receive\n // meaningful messages (e.g. for 429 \"Too Many Requests\" responses).\n let errorMessage: string = 'An error occurred';\n\n try {\n // Attempt to parse JSON error payload produced by backend\n const errorData = await response.json();\n const errorObj = errorData.error ?? errorData;\n errorMessage = JSON.stringify(errorObj) ?? 'An error occurred';\n } catch {\n // Fallback to plain-text body or HTTP status text\n try {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n } catch {\n // ignore – we already have a default message\n }\n }\n\n throw new Error(errorMessage);\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('No reader available');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const data = JSON.parse(line.slice(6));\n if (data.chunk) {\n onMessage?.(data.chunk);\n }\n if (data.done && data.response) {\n onDone?.(data.response);\n }\n } catch (e) {\n console.error('Failed to parse SSE data:', e);\n }\n }\n }\n }\n } catch (error) {\n console.error('Error in askDocQuestion:', error);\n throw error;\n }\n };\n\n const chat = async (body?: ChatBody, otherOptions: FetcherOptions = {}) => {\n if (!body) return;\n\n const { onMessage, onDone, onAction, ...rest } = body;\n const abortController = new AbortController();\n\n try {\n const response = await fetch(`${AI_API_ROUTE}/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authAPIOptions.headers,\n ...otherOptions.headers,\n },\n body: JSON.stringify({\n ...rest,\n ...authAPIOptions.body,\n ...otherOptions.body,\n }),\n signal: abortController.signal,\n credentials: 'include',\n });\n\n if (!response.ok) {\n let errorMessage: string = 'An error occurred';\n\n try {\n const errorData = await response.json();\n const errorObj = errorData.error ?? errorData;\n errorMessage = JSON.stringify(errorObj) ?? 'An error occurred';\n } catch {\n try {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n } catch {\n // ignore\n }\n }\n\n throw new Error(errorMessage);\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('No reader available');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const data = JSON.parse(line.slice(6));\n if (data.chunk) {\n onMessage?.(data.chunk);\n }\n if (data.action) {\n onAction?.(data.action);\n }\n if (data.done && data.response) {\n onDone?.(data.response);\n }\n } catch (e) {\n console.error('Failed to parse SSE data:', e);\n }\n }\n }\n }\n } catch (error) {\n console.error('Error in chat:', error);\n throw error;\n }\n };\n\n const autocomplete = async (\n body?: AutocompleteBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AutocompleteResponse>(\n `${AI_API_ROUTE}/autocomplete`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Retrieves discussions with filters and pagination. Only user or admin can access.\n */\n const getDiscussions = async (\n params?: GetDiscussionsParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetDiscussionsResult>(\n `${AI_API_ROUTE}/discussions`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n // @ts-ignore Number of parameter will be stringified by the fetcher\n params,\n }\n );\n\n /**\n * Retrieves aggregated AI token-usage statistics for the currently selected\n * project.\n */\n const getAIStats = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GetAIStatsResult>(\n `${AI_API_ROUTE}/stats`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n }\n );\n\n return {\n customQuery,\n translateJSON,\n auditContentDeclaration,\n auditContentDeclarationField,\n auditContentDeclarationMetadata,\n auditTag,\n askDocQuestion,\n chat,\n autocomplete,\n getDiscussions,\n getAIStats,\n };\n};\n\n/**\n * Authenticated `ai` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const aiEndpoint = createEndpoint(getAiAPI);\n"],"mappings":";;;;;;AAwDA,MAAa,YACX,iBAAiC,EAAE,EACnC,mBACG;CAGH,MAAM,eAAe,GAFF,gBAAgB,QAAQ,cAAcA,8BAAO,WAE7B;;;;;;CAOnC,MAAM,cAAc,OAClB,MACA,eAA+B,EAAE,KAEjC,MAAMC,wBACJ,cACA,gBACA,cACA;EACE,QAAQ;EACF;EACP,CACF;;;;;;CAOH,MAAM,gBAAgB,OACpB,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,aAAa,kBAChB,gBACA,cACA;EACE,QAAQ;EACF;EACP,CACF;;;;;;CAOH,MAAM,0BAA0B,OAC9B,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,aAAa,oBAChB,gBACA,cACA;EACE,QAAQ;EACF;EACP,CACF;;;;;;CAOH,MAAM,+BAA+B,OACnC,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,aAAa,0BAChB,gBACA,cACA;EACE,QAAQ;EACF;EACP,CACF;;;;;;CAOH,MAAM,kCAAkC,OACtC,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,aAAa,6BAChB,gBACA,cACA;EACE,QAAQ;EACF;EACP,CACF;;;;;;CAOH,MAAM,WAAW,OACf,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,aAAa,aAChB,gBACA,cACA;EACE,QAAQ;EACF;EACP,CACF;;;;;;;;;;;;;;;;;;;;CAqBH,MAAM,iBAAiB,OACrB,MACA,eAA+B,EAAE,KAC9B;AACH,MAAI,CAAC,KAAM;EAEX,MAAM,EAAE,WAAW,QAAQ,GAAG,SAAS;EACvC,MAAM,kBAAkB,IAAI,iBAAiB;AAE7C,MAAI;GACF,MAAM,WAAW,MAAM,MAAM,GAAG,aAAa,OAAO;IAClD,QAAQ;IACR,SAAS;KACP,gBAAgB;KAChB,GAAG,eAAe;KAClB,GAAG,aAAa;KACjB;IACD,MAAM,KAAK,UAAU;KACnB,GAAG;KACH,GAAG,eAAe;KAClB,GAAG,aAAa;KACjB,CAAC;IACF,QAAQ,gBAAgB;IACxB,aAAa;IACd,CAAC;AAEF,OAAI,CAAC,SAAS,IAAI;IAGhB,IAAI,eAAuB;AAE3B,QAAI;KAEF,MAAM,YAAY,MAAM,SAAS,MAAM;KACvC,MAAM,WAAW,UAAU,SAAS;AACpC,oBAAe,KAAK,UAAU,SAAS,IAAI;YACrC;AAEN,SAAI;MACF,MAAM,YAAY,MAAM,SAAS,MAAM;AACvC,UAAI,UACF,gBAAe;aAEX;;AAKV,UAAM,IAAI,MAAM,aAAa;;GAG/B,MAAM,SAAS,SAAS,MAAM,WAAW;AACzC,OAAI,CAAC,OACH,OAAM,IAAI,MAAM,sBAAsB;GAGxC,MAAM,UAAU,IAAI,aAAa;GACjC,IAAI,SAAS;AAEb,UAAO,MAAM;IACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,QAAI,KAAM;AAEV,cAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,MAAM,CAAC;IACjD,MAAM,QAAQ,OAAO,MAAM,KAAK;AAChC,aAAS,MAAM,KAAK,IAAI;AAExB,SAAK,MAAM,QAAQ,MACjB,KAAI,KAAK,WAAW,SAAS,CAC3B,KAAI;KACF,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM,EAAE,CAAC;AACtC,SAAI,KAAK,MACP,aAAY,KAAK,MAAM;AAEzB,SAAI,KAAK,QAAQ,KAAK,SACpB,UAAS,KAAK,SAAS;aAElB,GAAG;AACV,aAAQ,MAAM,6BAA6B,EAAE;;;WAK9C,OAAO;AACd,WAAQ,MAAM,4BAA4B,MAAM;AAChD,SAAM;;;CAIV,MAAM,OAAO,OAAO,MAAiB,eAA+B,EAAE,KAAK;AACzE,MAAI,CAAC,KAAM;EAEX,MAAM,EAAE,WAAW,QAAQ,UAAU,GAAG,SAAS;EACjD,MAAM,kBAAkB,IAAI,iBAAiB;AAE7C,MAAI;GACF,MAAM,WAAW,MAAM,MAAM,GAAG,aAAa,QAAQ;IACnD,QAAQ;IACR,SAAS;KACP,gBAAgB;KAChB,GAAG,eAAe;KAClB,GAAG,aAAa;KACjB;IACD,MAAM,KAAK,UAAU;KACnB,GAAG;KACH,GAAG,eAAe;KAClB,GAAG,aAAa;KACjB,CAAC;IACF,QAAQ,gBAAgB;IACxB,aAAa;IACd,CAAC;AAEF,OAAI,CAAC,SAAS,IAAI;IAChB,IAAI,eAAuB;AAE3B,QAAI;KACF,MAAM,YAAY,MAAM,SAAS,MAAM;KACvC,MAAM,WAAW,UAAU,SAAS;AACpC,oBAAe,KAAK,UAAU,SAAS,IAAI;YACrC;AACN,SAAI;MACF,MAAM,YAAY,MAAM,SAAS,MAAM;AACvC,UAAI,UACF,gBAAe;aAEX;;AAKV,UAAM,IAAI,MAAM,aAAa;;GAG/B,MAAM,SAAS,SAAS,MAAM,WAAW;AACzC,OAAI,CAAC,OACH,OAAM,IAAI,MAAM,sBAAsB;GAGxC,MAAM,UAAU,IAAI,aAAa;GACjC,IAAI,SAAS;AAEb,UAAO,MAAM;IACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,QAAI,KAAM;AAEV,cAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,MAAM,CAAC;IACjD,MAAM,QAAQ,OAAO,MAAM,KAAK;AAChC,aAAS,MAAM,KAAK,IAAI;AAExB,SAAK,MAAM,QAAQ,MACjB,KAAI,KAAK,WAAW,SAAS,CAC3B,KAAI;KACF,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM,EAAE,CAAC;AACtC,SAAI,KAAK,MACP,aAAY,KAAK,MAAM;AAEzB,SAAI,KAAK,OACP,YAAW,KAAK,OAAO;AAEzB,SAAI,KAAK,QAAQ,KAAK,SACpB,UAAS,KAAK,SAAS;aAElB,GAAG;AACV,aAAQ,MAAM,6BAA6B,EAAE;;;WAK9C,OAAO;AACd,WAAQ,MAAM,kBAAkB,MAAM;AACtC,SAAM;;;CAIV,MAAM,eAAe,OACnB,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,aAAa,gBAChB,gBACA,cACA;EACE,QAAQ;EACF;EACP,CACF;;;;CAKH,MAAM,iBAAiB,OACrB,QACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,aAAa,eAChB,gBACA,cACA;EACE,QAAQ;EAER;EACD,CACF;;;;;CAMH,MAAM,aAAa,OAAO,eAA+B,EAAE,KACzD,MAAMA,wBACJ,GAAG,aAAa,SAChB,gBACA,cACA,EACE,QAAQ,OACT,CACF;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;;;;;;;AASH,MAAa,aAAaC,6CAAe,SAAS"}
1
+ {"version":3,"file":"ai.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/ai.ts"],"sourcesContent":["import type {\n AIOptions,\n AskDocQuestionResult,\n AuditContentDeclarationBody,\n AuditContentDeclarationFieldBody,\n AuditContentDeclarationFieldResult,\n AuditContentDeclarationMetadataBody,\n AuditContentDeclarationMetadataResult,\n AuditContentDeclarationResult,\n AuditTagBody,\n AuditTagResult,\n AutocompleteResponse,\n ChatCompletionRequestMessage,\n ChatResult,\n CustomQueryBody,\n CustomQueryResult,\n GetAIStatsResult,\n GetDiscussionsParams,\n GetDiscussionsResult,\n TranslateJSONBody,\n TranslateJSONResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type AutocompleteBody = {\n text: string;\n aiOptions?: AIOptions;\n contextBefore?: string;\n currentLine?: string;\n contextAfter?: string;\n};\n\nexport type AskDocQuestionBody = {\n messages: ChatCompletionRequestMessage[];\n discussionId: string;\n onMessage?: (chunk: string) => void;\n onDone?: (response: AskDocQuestionResult) => void;\n};\n\nexport type ClientAction =\n | { type: 'navigate'; path: string }\n | { type: 'invalidate_queries' };\n\nexport type ChatBody = {\n messages: ChatCompletionRequestMessage[];\n discussionId: string;\n onMessage?: (chunk: string) => void;\n onDone?: (response: ChatResult) => void;\n onAction?: (action: ClientAction) => void;\n};\n\nexport type { AskDocQuestionResult, ChatResult };\n\nexport const getAiAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const AI_API_ROUTE = `${backendURL}/api/ai`;\n\n /**\n * Custom query\n * @param body - Custom query parameters.\n * @returns Custom query result.\n */\n const customQuery = async (\n body?: CustomQueryBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<CustomQueryResult>(\n AI_API_ROUTE,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Translate a JSON\n * @param body - Audit file parameters.\n * @returns Audited file content.\n */\n const translateJSON = async (\n body?: TranslateJSONBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<TranslateJSONResult>(\n `${AI_API_ROUTE}/translate/json`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Audits a content declaration file\n * @param body - Audit file parameters.\n * @returns Audited file content.\n */\n const auditContentDeclaration = async (\n body?: AuditContentDeclarationBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AuditContentDeclarationResult>(\n `${AI_API_ROUTE}/audit/dictionary`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Audits a content declaration field\n * @param body - Audit file parameters.\n * @returns Audited file content.\n */\n const auditContentDeclarationField = async (\n body?: AuditContentDeclarationFieldBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AuditContentDeclarationFieldResult>(\n `${AI_API_ROUTE}/audit/dictionary/field`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Audits a content declaration file to retrieve title, description and tags\n * @param body - Audit file parameters.\n * @returns Audited file content.\n */\n const auditContentDeclarationMetadata = async (\n body?: AuditContentDeclarationMetadataBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AuditContentDeclarationMetadataResult>(\n `${AI_API_ROUTE}/audit/dictionary/metadata`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Audits a tag\n * @param body - Audit tag parameters.\n * @returns Audited tag content.\n */\n const auditTag = async (\n body?: AuditTagBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AuditTagResult>(\n `${AI_API_ROUTE}/audit/tag`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Asks a question to the AI related to the documentation **and streams the\n * answer as Server‑Sent Events (SSE)**.\n *\n * The function **returns immediately** with a handle exposing:\n * - `promise` → resolves when the stream completes (or rejects on error)\n * - `abort()` → allows canceling the request on demand\n *\n * Usage example:\n * ```ts\n * const { promise, abort } = ai.askDocQuestion({\n * ...body,\n * onMessage: console.log,\n * onDone: (full) => console.log(\"✔\", full),\n * });\n * // later → abort();\n * await promise; // waits for completion if desired\n * ```\n */\n const askDocQuestion = async (\n body?: AskDocQuestionBody,\n otherOptions: FetcherOptions = {}\n ) => {\n if (!body) return;\n\n const { onMessage, onDone, ...rest } = body;\n const abortController = new AbortController();\n\n try {\n const response = await fetch(`${AI_API_ROUTE}/ask`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authAPIOptions.headers,\n ...otherOptions.headers,\n },\n body: JSON.stringify({\n ...rest,\n ...authAPIOptions.body,\n ...otherOptions.body,\n }),\n signal: abortController.signal,\n credentials: 'include',\n });\n\n if (!response.ok) {\n // Align error handling with generic `fetcher` utility so that callers receive\n // meaningful messages (e.g. for 429 \"Too Many Requests\" responses).\n let errorMessage: string = 'An error occurred';\n\n try {\n // Attempt to parse JSON error payload produced by backend\n const errorData = await response.json();\n const errorObj = errorData.error ?? errorData;\n errorMessage = JSON.stringify(errorObj) ?? 'An error occurred';\n } catch {\n // Fallback to plain-text body or HTTP status text\n try {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n } catch {\n // ignore – we already have a default message\n }\n }\n\n throw new Error(errorMessage);\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('No reader available');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const data = JSON.parse(line.slice(6));\n if (data.chunk) {\n onMessage?.(data.chunk);\n }\n if (data.done && data.response) {\n onDone?.(data.response);\n }\n } catch (e) {\n console.error('Failed to parse SSE data:', e);\n }\n }\n }\n }\n } catch (error) {\n console.error('Error in askDocQuestion:', error);\n throw error;\n }\n };\n\n const chat = async (body?: ChatBody, otherOptions: FetcherOptions = {}) => {\n if (!body) return;\n\n const { onMessage, onDone, onAction, ...rest } = body;\n const abortController = new AbortController();\n\n try {\n const response = await fetch(`${AI_API_ROUTE}/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authAPIOptions.headers,\n ...otherOptions.headers,\n },\n body: JSON.stringify({\n ...rest,\n ...authAPIOptions.body,\n ...otherOptions.body,\n }),\n signal: abortController.signal,\n credentials: 'include',\n });\n\n if (!response.ok) {\n let errorMessage: string = 'An error occurred';\n\n try {\n const errorData = await response.json();\n const errorObj = errorData.error ?? errorData;\n errorMessage = JSON.stringify(errorObj) ?? 'An error occurred';\n } catch {\n try {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n } catch {\n // ignore\n }\n }\n\n throw new Error(errorMessage);\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('No reader available');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const data = JSON.parse(line.slice(6));\n if (data.chunk) {\n onMessage?.(data.chunk);\n }\n if (data.action) {\n onAction?.(data.action);\n }\n if (data.done && data.response) {\n onDone?.(data.response);\n }\n } catch (e) {\n console.error('Failed to parse SSE data:', e);\n }\n }\n }\n }\n } catch (error) {\n console.error('Error in chat:', error);\n throw error;\n }\n };\n\n const autocomplete = async (\n body?: AutocompleteBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AutocompleteResponse>(\n `${AI_API_ROUTE}/autocomplete`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: body,\n }\n );\n\n /**\n * Retrieves discussions with filters and pagination. Only user or admin can access.\n */\n const getDiscussions = async (\n params?: GetDiscussionsParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetDiscussionsResult>(\n `${AI_API_ROUTE}/discussions`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n // @ts-ignore Number of parameter will be stringified by the fetcher\n params,\n }\n );\n\n /**\n * Retrieves aggregated AI token-usage statistics for the currently selected\n * project.\n */\n const getAIStats = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GetAIStatsResult>(\n `${AI_API_ROUTE}/stats`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n }\n );\n\n return {\n customQuery,\n translateJSON,\n auditContentDeclaration,\n auditContentDeclarationField,\n auditContentDeclarationMetadata,\n auditTag,\n askDocQuestion,\n chat,\n autocomplete,\n getDiscussions,\n getAIStats,\n };\n};\n\n/**\n * Authenticated `ai` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const aiEndpoint = createEndpoint(getAiAPI);\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/analytics.ts"],"sourcesContent":["import type {\n GetAnalyticsOverviewResult,\n GetAudienceResult,\n GetContentStatsResult,\n GetExperimentResultsResult,\n IngestAnalyticsBody,\n IngestAnalyticsResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getAnalyticsAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const ANALYTICS_API_ROUTE = `${backendURL}/api/analytics`;\n\n /**\n * Ingest a batch of analytics events. Public — attribution is by the\n * project's `clientId` in the body.\n * @param body - Session id, sdk version, and the collected events.\n * @returns The number of accepted events.\n */\n const sendEvents = async (\n body: IngestAnalyticsBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<IngestAnalyticsResult>(\n `${ANALYTICS_API_ROUTE}/events`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body,\n }\n );\n\n /**\n * Page/locale totals for the authenticated project.\n * @returns Views grouped by url and locale.\n */\n const getOverview = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GetAnalyticsOverviewResult>(\n `${ANALYTICS_API_ROUTE}/overview`,\n authAPIOptions,\n otherOptions,\n { method: 'GET' }\n );\n\n /**\n * Audience report: distinct visitors (today / 7d / window), page views, the\n * daily evolution series, and locale + country breakdowns.\n * @param days - Rolling window size in days (default 30).\n * @returns The audience statistics.\n */\n const getAudience = async (days = 30, otherOptions: FetcherOptions = {}) =>\n await fetcher<GetAudienceResult>(\n `${ANALYTICS_API_ROUTE}/audience`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n params: { days: String(days) },\n }\n );\n\n /**\n * Per-content exposure totals — \"which content is actually shown\".\n * @returns Exposures grouped by dictionary key, key path, and locale.\n */\n const getContentStats = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GetContentStatsResult>(\n `${ANALYTICS_API_ROUTE}/content-stats`,\n authAPIOptions,\n otherOptions,\n { method: 'GET' }\n );\n\n /**\n * A/B experiment results with per-variant conversion rates and significance.\n * @param experimentKey - The experiment to evaluate.\n * @returns The experiment result set.\n */\n const getExperimentResults = async (\n experimentKey: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetExperimentResultsResult>(\n `${ANALYTICS_API_ROUTE}/experiments/${experimentKey}`,\n authAPIOptions,\n otherOptions,\n { method: 'GET' }\n );\n\n return {\n sendEvents,\n getOverview,\n getAudience,\n getContentStats,\n getExperimentResults,\n };\n};\n\n/**\n * Authenticated `analytics` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const analyticsEndpoint = createEndpoint(getAnalyticsAPI);\n"],"mappings":";;;;;;AAaA,MAAa,mBACX,iBAAiC,EAAE,EACnC,mBACG;CAGH,MAAM,sBAAsB,GAFT,gBAAgB,QAAQ,cAAcA,8BAAO,WAEtB;;;;;;;CAQ1C,MAAM,aAAa,OACjB,MACA,eAA+B,EAAE,KAEjC,MAAMC,wBACJ,GAAG,oBAAoB,UACvB,gBACA,cACA;EACE,QAAQ;EACR;EACD,CACF;;;;;CAMH,MAAM,cAAc,OAAO,eAA+B,EAAE,KAC1D,MAAMA,wBACJ,GAAG,oBAAoB,YACvB,gBACA,cACA,EAAE,QAAQ,OAAO,CAClB;;;;;;;CAQH,MAAM,cAAc,OAAO,OAAO,IAAI,eAA+B,EAAE,KACrE,MAAMA,wBACJ,GAAG,oBAAoB,YACvB,gBACA,cACA;EACE,QAAQ;EACR,QAAQ,EAAE,MAAM,OAAO,KAAK,EAAE;EAC/B,CACF;;;;;CAMH,MAAM,kBAAkB,OAAO,eAA+B,EAAE,KAC9D,MAAMA,wBACJ,GAAG,oBAAoB,iBACvB,gBACA,cACA,EAAE,QAAQ,OAAO,CAClB;;;;;;CAOH,MAAM,uBAAuB,OAC3B,eACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,oBAAoB,eAAe,iBACtC,gBACA,cACA,EAAE,QAAQ,OAAO,CAClB;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACD;;;;;;;;AASH,MAAa,oBAAoBC,6CAAe,gBAAgB"}
1
+ {"version":3,"file":"analytics.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/analytics.ts"],"sourcesContent":["import type {\n GetAnalyticsOverviewResult,\n GetAudienceResult,\n GetContentStatsResult,\n GetExperimentResultsResult,\n IngestAnalyticsBody,\n IngestAnalyticsResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getAnalyticsAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const ANALYTICS_API_ROUTE = `${backendURL}/api/analytics`;\n\n /**\n * Ingest a batch of analytics events. Public — attribution is by the\n * project's `clientId` in the body.\n * @param body - Session id, sdk version, and the collected events.\n * @returns The number of accepted events.\n */\n const sendEvents = async (\n body: IngestAnalyticsBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<IngestAnalyticsResult>(\n `${ANALYTICS_API_ROUTE}/events`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body,\n }\n );\n\n /**\n * Page/locale totals for the authenticated project.\n * @returns Views grouped by url and locale.\n */\n const getOverview = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GetAnalyticsOverviewResult>(\n `${ANALYTICS_API_ROUTE}/overview`,\n authAPIOptions,\n otherOptions,\n { method: 'GET' }\n );\n\n /**\n * Audience report: distinct visitors (today / 7d / window), page views, the\n * daily evolution series, and locale + country breakdowns.\n * @param days - Rolling window size in days (default 30).\n * @returns The audience statistics.\n */\n const getAudience = async (days = 30, otherOptions: FetcherOptions = {}) =>\n await fetcher<GetAudienceResult>(\n `${ANALYTICS_API_ROUTE}/audience`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n params: { days: String(days) },\n }\n );\n\n /**\n * Per-content exposure totals — \"which content is actually shown\".\n * @returns Exposures grouped by dictionary key, key path, and locale.\n */\n const getContentStats = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GetContentStatsResult>(\n `${ANALYTICS_API_ROUTE}/content-stats`,\n authAPIOptions,\n otherOptions,\n { method: 'GET' }\n );\n\n /**\n * A/B experiment results with per-variant conversion rates and significance.\n * @param experimentKey - The experiment to evaluate.\n * @returns The experiment result set.\n */\n const getExperimentResults = async (\n experimentKey: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetExperimentResultsResult>(\n `${ANALYTICS_API_ROUTE}/experiments/${experimentKey}`,\n authAPIOptions,\n otherOptions,\n { method: 'GET' }\n );\n\n return {\n sendEvents,\n getOverview,\n getAudience,\n getContentStats,\n getExperimentResults,\n };\n};\n\n/**\n * Authenticated `analytics` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const analyticsEndpoint = createEndpoint(getAnalyticsAPI);\n"],"mappings":";;;;;;AAaA,MAAa,mBACX,iBAAiC,CAAC,GAClC,mBACG;CAGH,MAAM,sBAAsB,GAFT,gBAAgB,QAAQ,cAAcA,8BAAO,WAEtB;;;;;;;CAQ1C,MAAM,aAAa,OACjB,MACA,eAA+B,CAAC,MAEhC,MAAMC,wBACJ,GAAG,oBAAoB,UACvB,gBACA,cACA;EACE,QAAQ;EACR;CACF,CACF;;;;;CAMF,MAAM,cAAc,OAAO,eAA+B,CAAC,MACzD,MAAMA,wBACJ,GAAG,oBAAoB,YACvB,gBACA,cACA,EAAE,QAAQ,MAAM,CAClB;;;;;;;CAQF,MAAM,cAAc,OAAO,OAAO,IAAI,eAA+B,CAAC,MACpE,MAAMA,wBACJ,GAAG,oBAAoB,YACvB,gBACA,cACA;EACE,QAAQ;EACR,QAAQ,EAAE,MAAM,OAAO,IAAI,EAAE;CAC/B,CACF;;;;;CAMF,MAAM,kBAAkB,OAAO,eAA+B,CAAC,MAC7D,MAAMA,wBACJ,GAAG,oBAAoB,iBACvB,gBACA,cACA,EAAE,QAAQ,MAAM,CAClB;;;;;;CAOF,MAAM,uBAAuB,OAC3B,eACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,oBAAoB,eAAe,iBACtC,gBACA,cACA,EAAE,QAAQ,MAAM,CAClB;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;;AAQA,MAAa,oBAAoBC,6CAAe,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"asset.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/asset.ts"],"sourcesContent":["import type {\n DeleteAssetResult,\n GetAssetByIdResult,\n GetAssetsResult,\n UpdateAssetResult,\n UploadAssetResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getAssetAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const ASSET_API_ROUTE = `${backendURL}/api/assets`;\n\n /**\n * Retrieves all assets for the current session project, paginated.\n * @param page - Page number (1-based).\n * @param pageSize - Number of items per page.\n * @returns Paginated list of assets.\n */\n const getAssets = async (\n page?: number,\n pageSize?: number,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetAssetsResult>(\n ASSET_API_ROUTE,\n authAPIOptions,\n otherOptions,\n {\n cache: 'no-store',\n params: {\n ...(page !== undefined && { page: String(page) }),\n ...(pageSize !== undefined && { pageSize: String(pageSize) }),\n },\n }\n );\n\n /**\n * Retrieves a single asset by ID.\n * @param assetId - The asset document ID.\n * @returns The asset.\n */\n const getAssetById = async (\n assetId: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetAssetByIdResult>(\n `${ASSET_API_ROUTE}/${assetId}`,\n authAPIOptions,\n otherOptions,\n { cache: 'no-store' }\n );\n\n /**\n * Uploads a new asset image.\n * @param file - The image File object.\n * @param alt - Optional alt text.\n * @param caption - Optional caption.\n * @returns The created asset record with its public URL.\n */\n const uploadAsset = async (\n file: File,\n alt?: string,\n caption?: string,\n otherOptions: FetcherOptions = {}\n ) => {\n const buffer = await file.arrayBuffer();\n\n const headers: Record<string, string> = {\n 'Content-Type': file.type || 'image/jpeg',\n 'X-File-Name': file.name,\n };\n\n if (alt) headers['X-Alt-Text'] = alt;\n if (caption) headers['X-Caption'] = caption;\n\n const authHeaders =\n (authAPIOptions.headers as Record<string, string> | undefined) ?? {};\n\n const response = await fetch(ASSET_API_ROUTE, {\n method: 'POST',\n credentials: 'include',\n headers: { ...authHeaders, ...headers },\n body: buffer,\n signal: otherOptions.signal as AbortSignal | undefined,\n });\n\n if (!response.ok) {\n const result = await response.json();\n throw new Error(JSON.stringify(result.error) ?? 'Asset upload failed');\n }\n\n return (await response.json()) as UploadAssetResult;\n };\n\n /**\n * Updates mutable metadata (name, alt text, caption) of an asset.\n * @param assetId - The asset document ID.\n * @param data - Fields to update.\n * @returns The updated asset record.\n */\n const updateAsset = async (\n assetId: string,\n data: { originalName?: string; alt?: string; caption?: string },\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<UpdateAssetResult>(\n `${ASSET_API_ROUTE}/${assetId}`,\n authAPIOptions,\n otherOptions,\n { method: 'PATCH', body: data as unknown as Record<string, unknown> }\n );\n\n /**\n * Deletes an asset by ID.\n * @param assetId - The asset document ID.\n * @returns Confirmation response.\n */\n const deleteAsset = async (\n assetId: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<DeleteAssetResult>(\n `${ASSET_API_ROUTE}/${assetId}`,\n authAPIOptions,\n otherOptions,\n { method: 'DELETE' }\n );\n\n return {\n getAssets,\n getAssetById,\n uploadAsset,\n updateAsset,\n deleteAsset,\n };\n};\n\n/**\n * Authenticated `asset` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const assetEndpoint = createEndpoint(getAssetAPI);\n"],"mappings":";;;;;;AAYA,MAAa,eACX,iBAAiC,EAAE,EACnC,mBACG;CAGH,MAAM,kBAAkB,GAFL,gBAAgB,QAAQ,cAAcA,8BAAO,WAE1B;;;;;;;CAQtC,MAAM,YAAY,OAChB,MACA,UACA,eAA+B,EAAE,KAEjC,MAAMC,wBACJ,iBACA,gBACA,cACA;EACE,OAAO;EACP,QAAQ;GACN,GAAI,SAAS,UAAa,EAAE,MAAM,OAAO,KAAK,EAAE;GAChD,GAAI,aAAa,UAAa,EAAE,UAAU,OAAO,SAAS,EAAE;GAC7D;EACF,CACF;;;;;;CAOH,MAAM,eAAe,OACnB,SACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,gBAAgB,GAAG,WACtB,gBACA,cACA,EAAE,OAAO,YAAY,CACtB;;;;;;;;CASH,MAAM,cAAc,OAClB,MACA,KACA,SACA,eAA+B,EAAE,KAC9B;EACH,MAAM,SAAS,MAAM,KAAK,aAAa;EAEvC,MAAM,UAAkC;GACtC,gBAAgB,KAAK,QAAQ;GAC7B,eAAe,KAAK;GACrB;AAED,MAAI,IAAK,SAAQ,gBAAgB;AACjC,MAAI,QAAS,SAAQ,eAAe;EAEpC,MAAM,cACH,eAAe,WAAkD,EAAE;EAEtE,MAAM,WAAW,MAAM,MAAM,iBAAiB;GAC5C,QAAQ;GACR,aAAa;GACb,SAAS;IAAE,GAAG;IAAa,GAAG;IAAS;GACvC,MAAM;GACN,QAAQ,aAAa;GACtB,CAAC;AAEF,MAAI,CAAC,SAAS,IAAI;GAChB,MAAM,SAAS,MAAM,SAAS,MAAM;AACpC,SAAM,IAAI,MAAM,KAAK,UAAU,OAAO,MAAM,IAAI,sBAAsB;;AAGxE,SAAQ,MAAM,SAAS,MAAM;;;;;;;;CAS/B,MAAM,cAAc,OAClB,SACA,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,gBAAgB,GAAG,WACtB,gBACA,cACA;EAAE,QAAQ;EAAS,MAAM;EAA4C,CACtE;;;;;;CAOH,MAAM,cAAc,OAClB,SACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,gBAAgB,GAAG,WACtB,gBACA,cACA,EAAE,QAAQ,UAAU,CACrB;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACD;;;;;;;;AASH,MAAa,gBAAgBC,6CAAe,YAAY"}
1
+ {"version":3,"file":"asset.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/asset.ts"],"sourcesContent":["import type {\n DeleteAssetResult,\n GetAssetByIdResult,\n GetAssetsResult,\n UpdateAssetResult,\n UploadAssetResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getAssetAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const ASSET_API_ROUTE = `${backendURL}/api/assets`;\n\n /**\n * Retrieves all assets for the current session project, paginated.\n * @param page - Page number (1-based).\n * @param pageSize - Number of items per page.\n * @returns Paginated list of assets.\n */\n const getAssets = async (\n page?: number,\n pageSize?: number,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetAssetsResult>(\n ASSET_API_ROUTE,\n authAPIOptions,\n otherOptions,\n {\n cache: 'no-store',\n params: {\n ...(page !== undefined && { page: String(page) }),\n ...(pageSize !== undefined && { pageSize: String(pageSize) }),\n },\n }\n );\n\n /**\n * Retrieves a single asset by ID.\n * @param assetId - The asset document ID.\n * @returns The asset.\n */\n const getAssetById = async (\n assetId: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetAssetByIdResult>(\n `${ASSET_API_ROUTE}/${assetId}`,\n authAPIOptions,\n otherOptions,\n { cache: 'no-store' }\n );\n\n /**\n * Uploads a new asset image.\n * @param file - The image File object.\n * @param alt - Optional alt text.\n * @param caption - Optional caption.\n * @returns The created asset record with its public URL.\n */\n const uploadAsset = async (\n file: File,\n alt?: string,\n caption?: string,\n otherOptions: FetcherOptions = {}\n ) => {\n const buffer = await file.arrayBuffer();\n\n const headers: Record<string, string> = {\n 'Content-Type': file.type || 'image/jpeg',\n 'X-File-Name': file.name,\n };\n\n if (alt) headers['X-Alt-Text'] = alt;\n if (caption) headers['X-Caption'] = caption;\n\n const authHeaders =\n (authAPIOptions.headers as Record<string, string> | undefined) ?? {};\n\n const response = await fetch(ASSET_API_ROUTE, {\n method: 'POST',\n credentials: 'include',\n headers: { ...authHeaders, ...headers },\n body: buffer,\n signal: otherOptions.signal as AbortSignal | undefined,\n });\n\n if (!response.ok) {\n const result = await response.json();\n throw new Error(JSON.stringify(result.error) ?? 'Asset upload failed');\n }\n\n return (await response.json()) as UploadAssetResult;\n };\n\n /**\n * Updates mutable metadata (name, alt text, caption) of an asset.\n * @param assetId - The asset document ID.\n * @param data - Fields to update.\n * @returns The updated asset record.\n */\n const updateAsset = async (\n assetId: string,\n data: { originalName?: string; alt?: string; caption?: string },\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<UpdateAssetResult>(\n `${ASSET_API_ROUTE}/${assetId}`,\n authAPIOptions,\n otherOptions,\n { method: 'PATCH', body: data as unknown as Record<string, unknown> }\n );\n\n /**\n * Deletes an asset by ID.\n * @param assetId - The asset document ID.\n * @returns Confirmation response.\n */\n const deleteAsset = async (\n assetId: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<DeleteAssetResult>(\n `${ASSET_API_ROUTE}/${assetId}`,\n authAPIOptions,\n otherOptions,\n { method: 'DELETE' }\n );\n\n return {\n getAssets,\n getAssetById,\n uploadAsset,\n updateAsset,\n deleteAsset,\n };\n};\n\n/**\n * Authenticated `asset` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const assetEndpoint = createEndpoint(getAssetAPI);\n"],"mappings":";;;;;;AAYA,MAAa,eACX,iBAAiC,CAAC,GAClC,mBACG;CAGH,MAAM,kBAAkB,GAFL,gBAAgB,QAAQ,cAAcA,8BAAO,WAE1B;;;;;;;CAQtC,MAAM,YAAY,OAChB,MACA,UACA,eAA+B,CAAC,MAEhC,MAAMC,wBACJ,iBACA,gBACA,cACA;EACE,OAAO;EACP,QAAQ;GACN,GAAI,SAAS,UAAa,EAAE,MAAM,OAAO,IAAI,EAAE;GAC/C,GAAI,aAAa,UAAa,EAAE,UAAU,OAAO,QAAQ,EAAE;EAC7D;CACF,CACF;;;;;;CAOF,MAAM,eAAe,OACnB,SACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,gBAAgB,GAAG,WACtB,gBACA,cACA,EAAE,OAAO,WAAW,CACtB;;;;;;;;CASF,MAAM,cAAc,OAClB,MACA,KACA,SACA,eAA+B,CAAC,MAC7B;EACH,MAAM,SAAS,MAAM,KAAK,YAAY;EAEtC,MAAM,UAAkC;GACtC,gBAAgB,KAAK,QAAQ;GAC7B,eAAe,KAAK;EACtB;EAEA,IAAI,KAAK,QAAQ,gBAAgB;EACjC,IAAI,SAAS,QAAQ,eAAe;EAEpC,MAAM,cACH,eAAe,WAAkD,CAAC;EAErE,MAAM,WAAW,MAAM,MAAM,iBAAiB;GAC5C,QAAQ;GACR,aAAa;GACb,SAAS;IAAE,GAAG;IAAa,GAAG;GAAQ;GACtC,MAAM;GACN,QAAQ,aAAa;EACvB,CAAC;EAED,IAAI,CAAC,SAAS,IAAI;GAChB,MAAM,SAAS,MAAM,SAAS,KAAK;GACnC,MAAM,IAAI,MAAM,KAAK,UAAU,OAAO,KAAK,KAAK,qBAAqB;EACvE;EAEA,OAAQ,MAAM,SAAS,KAAK;CAC9B;;;;;;;CAQA,MAAM,cAAc,OAClB,SACA,MACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,gBAAgB,GAAG,WACtB,gBACA,cACA;EAAE,QAAQ;EAAS,MAAM;CAA2C,CACtE;;;;;;CAOF,MAAM,cAAc,OAClB,SACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,gBAAgB,GAAG,WACtB,gBACA,cACA,EAAE,QAAQ,SAAS,CACrB;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;;AAQA,MAAa,gBAAgBC,6CAAe,WAAW"}
@@ -25,7 +25,8 @@ const getAuditAPI = (authAPIOptions = {}, intlayerConfig) => {
25
25
  const scanUrl = async (body, otherOptions = {}) => {
26
26
  if (!body?.url) return;
27
27
  const { url, onMessage, onDone } = body;
28
- const endpoint = `${AUDIT_API_ROUTE}?${new URLSearchParams({ url }).toString()}`;
28
+ const params = new URLSearchParams({ url });
29
+ const endpoint = `${AUDIT_API_ROUTE}?${params.toString()}`;
29
30
  const response = await fetch(endpoint, {
30
31
  method: "GET",
31
32
  headers: {
@@ -1 +1 @@
1
- {"version":3,"file":"audit.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/audit.ts"],"sourcesContent":["import type {\n AuditEvent,\n GetRecursiveAuditStatusResult,\n StartRecursiveAuditResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type {\n AuditEvent,\n GetRecursiveAuditStatusResult,\n StartRecursiveAuditResult,\n};\n\nexport type ScanUrlBody = {\n url: string;\n onMessage?: (event: AuditEvent) => void;\n onDone?: () => void;\n};\n\nexport type DiscoverUrlsParams = {\n url: string;\n};\n\nexport type DiscoverUrlsResult = {\n urls: string[];\n};\n\nexport type StartRecursiveAuditBody = {\n url: string;\n urls?: string[];\n};\n\nexport type GetRecursiveAuditStatusParams = {\n jobId: string;\n};\n\nexport type RecursiveAuditJobParams = {\n jobId: string;\n};\n\nexport const getAuditAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const AUDIT_API_ROUTE = `${backendURL}/api/scan`;\n\n /**\n * Streams a single-page SEO audit as Server-Sent Events.\n *\n * Usage:\n * ```ts\n * await audit.scanUrl({\n * url: 'https://example.com',\n * onMessage: (event) => console.log(event),\n * onDone: () => console.log('done'),\n * });\n * ```\n */\n const discoverUrls = async (\n params?: DiscoverUrlsParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<DiscoverUrlsResult>(\n `${AUDIT_API_ROUTE}/recursive/discover`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n params,\n }\n );\n\n const scanUrl = async (\n body?: ScanUrlBody,\n otherOptions: FetcherOptions = {}\n ) => {\n if (!body?.url) return;\n\n const { url, onMessage, onDone } = body;\n\n const params = new URLSearchParams({ url });\n const endpoint = `${AUDIT_API_ROUTE}?${params.toString()}`;\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n Accept: 'text/event-stream',\n ...authAPIOptions.headers,\n ...otherOptions.headers,\n },\n credentials: 'include',\n signal: otherOptions.signal,\n });\n\n if (!response.ok) {\n let errorMessage = 'An error occurred';\n try {\n const errorData = await response.json();\n errorMessage = JSON.stringify(errorData.error) ?? errorMessage;\n } catch {\n try {\n const errorText = await response.text();\n if (errorText) errorMessage = errorText;\n } catch {\n // ignore\n }\n }\n throw new Error(errorMessage);\n }\n\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No reader available');\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const event = JSON.parse(line.slice(6)) as AuditEvent;\n onMessage?.(event);\n } catch {\n // ignore malformed lines\n }\n }\n }\n }\n\n onDone?.();\n };\n\n /**\n * Starts a recursive audit job for the given URL.\n */\n const startRecursiveAudit = async (\n body?: StartRecursiveAuditBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<StartRecursiveAuditResult>(\n `${AUDIT_API_ROUTE}/recursive/start`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n params: body?.url ? { url: body.url } : undefined,\n body: body?.urls !== undefined ? { urls: body.urls as any } : undefined,\n }\n );\n\n /**\n * Gets the status of a recursive audit job.\n */\n const getRecursiveAuditStatus = async (\n params?: GetRecursiveAuditStatusParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetRecursiveAuditStatusResult>(\n `${AUDIT_API_ROUTE}/recursive/${params?.jobId}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n }\n );\n\n const cancelRecursiveAudit = async (\n params?: RecursiveAuditJobParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<{ success: boolean }>(\n `${AUDIT_API_ROUTE}/recursive/${params?.jobId}/cancel`,\n authAPIOptions,\n otherOptions,\n { method: 'POST' }\n );\n\n const pauseRecursiveAudit = async (\n params?: RecursiveAuditJobParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<{ success: boolean }>(\n `${AUDIT_API_ROUTE}/recursive/${params?.jobId}/pause`,\n authAPIOptions,\n otherOptions,\n { method: 'POST' }\n );\n\n const resumeRecursiveAudit = async (\n params?: RecursiveAuditJobParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<{ success: boolean }>(\n `${AUDIT_API_ROUTE}/recursive/${params?.jobId}/resume`,\n authAPIOptions,\n otherOptions,\n { method: 'POST' }\n );\n\n return {\n discoverUrls,\n scanUrl,\n startRecursiveAudit,\n getRecursiveAuditStatus,\n cancelRecursiveAudit,\n pauseRecursiveAudit,\n resumeRecursiveAudit,\n };\n};\n\n/**\n * Authenticated `audit` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const auditEndpoint = createEndpoint(getAuditAPI);\n"],"mappings":";;;;;;AA2CA,MAAa,eACX,iBAAiC,EAAE,EACnC,mBACG;CAGH,MAAM,kBAAkB,GAFL,gBAAgB,QAAQ,cAAcA,8BAAO,WAE1B;;;;;;;;;;;;;CActC,MAAM,eAAe,OACnB,QACA,eAA+B,EAAE,KAEjC,MAAMC,wBACJ,GAAG,gBAAgB,sBACnB,gBACA,cACA;EACE,QAAQ;EACR;EACD,CACF;CAEH,MAAM,UAAU,OACd,MACA,eAA+B,EAAE,KAC9B;AACH,MAAI,CAAC,MAAM,IAAK;EAEhB,MAAM,EAAE,KAAK,WAAW,WAAW;EAGnC,MAAM,WAAW,GAAG,gBAAgB,GAAG,IADpB,gBAAgB,EAAE,KAAK,CACG,CAAC,UAAU;EAExD,MAAM,WAAW,MAAM,MAAM,UAAU;GACrC,QAAQ;GACR,SAAS;IACP,QAAQ;IACR,GAAG,eAAe;IAClB,GAAG,aAAa;IACjB;GACD,aAAa;GACb,QAAQ,aAAa;GACtB,CAAC;AAEF,MAAI,CAAC,SAAS,IAAI;GAChB,IAAI,eAAe;AACnB,OAAI;IACF,MAAM,YAAY,MAAM,SAAS,MAAM;AACvC,mBAAe,KAAK,UAAU,UAAU,MAAM,IAAI;WAC5C;AACN,QAAI;KACF,MAAM,YAAY,MAAM,SAAS,MAAM;AACvC,SAAI,UAAW,gBAAe;YACxB;;AAIV,SAAM,IAAI,MAAM,aAAa;;EAG/B,MAAM,SAAS,SAAS,MAAM,WAAW;AACzC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,sBAAsB;EAEnD,MAAM,UAAU,IAAI,aAAa;EACjC,IAAI,SAAS;AAEb,SAAO,MAAM;GACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAE3C,OAAI,KAAM;AAEV,aAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,MAAM,CAAC;GACjD,MAAM,QAAQ,OAAO,MAAM,KAAK;AAChC,YAAS,MAAM,KAAK,IAAI;AAExB,QAAK,MAAM,QAAQ,MACjB,KAAI,KAAK,WAAW,SAAS,CAC3B,KAAI;IACF,MAAM,QAAQ,KAAK,MAAM,KAAK,MAAM,EAAE,CAAC;AACvC,gBAAY,MAAM;WACZ;;AAOd,YAAU;;;;;CAMZ,MAAM,sBAAsB,OAC1B,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,gBAAgB,mBACnB,gBACA,cACA;EACE,QAAQ;EACR,QAAQ,MAAM,MAAM,EAAE,KAAK,KAAK,KAAK,GAAG;EACxC,MAAM,MAAM,SAAS,SAAY,EAAE,MAAM,KAAK,MAAa,GAAG;EAC/D,CACF;;;;CAKH,MAAM,0BAA0B,OAC9B,QACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,gBAAgB,aAAa,QAAQ,SACxC,gBACA,cACA,EACE,QAAQ,OACT,CACF;CAEH,MAAM,uBAAuB,OAC3B,QACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,gBAAgB,aAAa,QAAQ,MAAM,UAC9C,gBACA,cACA,EAAE,QAAQ,QAAQ,CACnB;CAEH,MAAM,sBAAsB,OAC1B,QACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,gBAAgB,aAAa,QAAQ,MAAM,SAC9C,gBACA,cACA,EAAE,QAAQ,QAAQ,CACnB;CAEH,MAAM,uBAAuB,OAC3B,QACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,gBAAgB,aAAa,QAAQ,MAAM,UAC9C,gBACA,cACA,EAAE,QAAQ,QAAQ,CACnB;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;;;;;;;AASH,MAAa,gBAAgBC,6CAAe,YAAY"}
1
+ {"version":3,"file":"audit.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/audit.ts"],"sourcesContent":["import type {\n AuditEvent,\n GetRecursiveAuditStatusResult,\n StartRecursiveAuditResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type {\n AuditEvent,\n GetRecursiveAuditStatusResult,\n StartRecursiveAuditResult,\n};\n\nexport type ScanUrlBody = {\n url: string;\n onMessage?: (event: AuditEvent) => void;\n onDone?: () => void;\n};\n\nexport type DiscoverUrlsParams = {\n url: string;\n};\n\nexport type DiscoverUrlsResult = {\n urls: string[];\n};\n\nexport type StartRecursiveAuditBody = {\n url: string;\n urls?: string[];\n};\n\nexport type GetRecursiveAuditStatusParams = {\n jobId: string;\n};\n\nexport type RecursiveAuditJobParams = {\n jobId: string;\n};\n\nexport const getAuditAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const AUDIT_API_ROUTE = `${backendURL}/api/scan`;\n\n /**\n * Streams a single-page SEO audit as Server-Sent Events.\n *\n * Usage:\n * ```ts\n * await audit.scanUrl({\n * url: 'https://example.com',\n * onMessage: (event) => console.log(event),\n * onDone: () => console.log('done'),\n * });\n * ```\n */\n const discoverUrls = async (\n params?: DiscoverUrlsParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<DiscoverUrlsResult>(\n `${AUDIT_API_ROUTE}/recursive/discover`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n params,\n }\n );\n\n const scanUrl = async (\n body?: ScanUrlBody,\n otherOptions: FetcherOptions = {}\n ) => {\n if (!body?.url) return;\n\n const { url, onMessage, onDone } = body;\n\n const params = new URLSearchParams({ url });\n const endpoint = `${AUDIT_API_ROUTE}?${params.toString()}`;\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n Accept: 'text/event-stream',\n ...authAPIOptions.headers,\n ...otherOptions.headers,\n },\n credentials: 'include',\n signal: otherOptions.signal,\n });\n\n if (!response.ok) {\n let errorMessage = 'An error occurred';\n try {\n const errorData = await response.json();\n errorMessage = JSON.stringify(errorData.error) ?? errorMessage;\n } catch {\n try {\n const errorText = await response.text();\n if (errorText) errorMessage = errorText;\n } catch {\n // ignore\n }\n }\n throw new Error(errorMessage);\n }\n\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No reader available');\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const event = JSON.parse(line.slice(6)) as AuditEvent;\n onMessage?.(event);\n } catch {\n // ignore malformed lines\n }\n }\n }\n }\n\n onDone?.();\n };\n\n /**\n * Starts a recursive audit job for the given URL.\n */\n const startRecursiveAudit = async (\n body?: StartRecursiveAuditBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<StartRecursiveAuditResult>(\n `${AUDIT_API_ROUTE}/recursive/start`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n params: body?.url ? { url: body.url } : undefined,\n body: body?.urls !== undefined ? { urls: body.urls as any } : undefined,\n }\n );\n\n /**\n * Gets the status of a recursive audit job.\n */\n const getRecursiveAuditStatus = async (\n params?: GetRecursiveAuditStatusParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetRecursiveAuditStatusResult>(\n `${AUDIT_API_ROUTE}/recursive/${params?.jobId}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'GET',\n }\n );\n\n const cancelRecursiveAudit = async (\n params?: RecursiveAuditJobParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<{ success: boolean }>(\n `${AUDIT_API_ROUTE}/recursive/${params?.jobId}/cancel`,\n authAPIOptions,\n otherOptions,\n { method: 'POST' }\n );\n\n const pauseRecursiveAudit = async (\n params?: RecursiveAuditJobParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<{ success: boolean }>(\n `${AUDIT_API_ROUTE}/recursive/${params?.jobId}/pause`,\n authAPIOptions,\n otherOptions,\n { method: 'POST' }\n );\n\n const resumeRecursiveAudit = async (\n params?: RecursiveAuditJobParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<{ success: boolean }>(\n `${AUDIT_API_ROUTE}/recursive/${params?.jobId}/resume`,\n authAPIOptions,\n otherOptions,\n { method: 'POST' }\n );\n\n return {\n discoverUrls,\n scanUrl,\n startRecursiveAudit,\n getRecursiveAuditStatus,\n cancelRecursiveAudit,\n pauseRecursiveAudit,\n resumeRecursiveAudit,\n };\n};\n\n/**\n * Authenticated `audit` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const auditEndpoint = createEndpoint(getAuditAPI);\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"bitbucket.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/bitbucket.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type BitbucketRepository = {\n uuid: string;\n name: string;\n full_name: string;\n slug: string;\n mainbranch?: {\n name: string;\n type: string;\n };\n links: {\n html: {\n href: string;\n };\n };\n workspace: {\n slug: string;\n name: string;\n uuid: string;\n };\n owner: {\n display_name: string;\n username?: string;\n uuid: string;\n };\n updated_on: string;\n is_private: boolean;\n};\n\nexport type BitbucketAuthCallbackBody = {\n code: string;\n};\n\nexport type BitbucketAuthCallbackResult = {\n data: {\n token: string;\n };\n};\n\nexport type BitbucketListReposResult = {\n data: BitbucketRepository[];\n};\n\nexport type BitbucketCheckConfigBody = {\n token?: string;\n workspace: string;\n repoSlug: string;\n branch?: string;\n};\n\nexport type BitbucketCheckConfigResult = {\n data: {\n hasConfig: boolean;\n configPaths: string[];\n };\n};\n\nexport type BitbucketGetConfigFileBody = {\n token?: string;\n workspace: string;\n repoSlug: string;\n branch?: string;\n path?: string;\n};\n\nexport type BitbucketGetConfigFileResult = {\n data: {\n content: string;\n };\n};\n\nexport type BitbucketGetAuthUrlResult = {\n data: {\n authUrl: string;\n };\n};\n\nexport const getBitbucketAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const BITBUCKET_API_ROUTE = `${backendURL}/api/bitbucket`;\n\n /**\n * Get Bitbucket OAuth authorization URL\n * @param redirectUri - Redirect URI after OAuth authorization\n */\n const getAuthUrl = async (\n redirectUri: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketGetAuthUrlResult>(\n `${BITBUCKET_API_ROUTE}/auth-url`,\n authAPIOptions,\n otherOptions,\n {\n params: { redirectUri },\n }\n );\n\n /**\n * Exchange Bitbucket authorization code for access token\n * @param code - Bitbucket authorization code\n */\n const authenticate = async (\n code: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketAuthCallbackResult>(\n `${BITBUCKET_API_ROUTE}/auth`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { code },\n }\n );\n\n /**\n * Get user's Bitbucket repositories\n * @param token - Optional Bitbucket access token. If not provided, backend will use session.\n */\n const getRepositories = async (\n token?: string | null,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketListReposResult>(\n `${BITBUCKET_API_ROUTE}/repos`,\n authAPIOptions,\n otherOptions,\n {\n params: token ? { token } : undefined,\n }\n );\n\n /**\n * Check if intlayer.config.ts exists in a Bitbucket repository\n * @param token - Optional Bitbucket access token. If not provided, backend will use session.\n * @param workspace - Bitbucket workspace slug\n * @param repoSlug - Repository slug\n * @param branch - Branch name (default: 'main')\n */\n const checkIntlayerConfig = async (\n token: string | null | undefined,\n workspace: string,\n repoSlug: string,\n branch: string = 'main',\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketCheckConfigResult>(\n `${BITBUCKET_API_ROUTE}/check-config`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { token: token ?? undefined, workspace, repoSlug, branch },\n }\n );\n\n /**\n * Get intlayer.config.ts file contents from a Bitbucket repository\n * @param token - Optional Bitbucket access token. If not provided, backend will use session.\n * @param workspace - Bitbucket workspace slug\n * @param repoSlug - Repository slug\n * @param branch - Branch name (default: 'main')\n * @param path - File path (default: 'intlayer.config.ts')\n */\n const getConfigFile = async (\n token: string | null | undefined,\n workspace: string,\n repoSlug: string,\n branch: string = 'main',\n path: string = 'intlayer.config.ts',\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketGetConfigFileResult>(\n `${BITBUCKET_API_ROUTE}/get-config-file`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: {\n token: token ?? undefined,\n workspace,\n repoSlug,\n branch,\n path,\n },\n }\n );\n\n return {\n getAuthUrl,\n authenticate,\n getRepositories,\n checkIntlayerConfig,\n getConfigFile,\n };\n};\n\n/**\n * Authenticated `bitbucket` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const bitbucketEndpoint = createEndpoint(getBitbucketAPI);\n"],"mappings":";;;;;;AAiFA,MAAa,mBACX,iBAAiC,EAAE,EACnC,mBACG;CAGH,MAAM,sBAAsB,GAFT,gBAAgB,QAAQ,cAAcA,8BAAO,WAEtB;;;;;CAM1C,MAAM,aAAa,OACjB,aACA,eAA+B,EAAE,KAEjC,MAAMC,wBACJ,GAAG,oBAAoB,YACvB,gBACA,cACA,EACE,QAAQ,EAAE,aAAa,EACxB,CACF;;;;;CAMH,MAAM,eAAe,OACnB,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,oBAAoB,QACvB,gBACA,cACA;EACE,QAAQ;EACR,MAAM,EAAE,MAAM;EACf,CACF;;;;;CAMH,MAAM,kBAAkB,OACtB,OACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,oBAAoB,SACvB,gBACA,cACA,EACE,QAAQ,QAAQ,EAAE,OAAO,GAAG,QAC7B,CACF;;;;;;;;CASH,MAAM,sBAAsB,OAC1B,OACA,WACA,UACA,SAAiB,QACjB,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,oBAAoB,gBACvB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GAAE,OAAO,SAAS;GAAW;GAAW;GAAU;GAAQ;EACjE,CACF;;;;;;;;;CAUH,MAAM,gBAAgB,OACpB,OACA,WACA,UACA,SAAiB,QACjB,OAAe,sBACf,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,oBAAoB,mBACvB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GACJ,OAAO,SAAS;GAChB;GACA;GACA;GACA;GACD;EACF,CACF;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACD;;;;;;;;AASH,MAAa,oBAAoBC,6CAAe,gBAAgB"}
1
+ {"version":3,"file":"bitbucket.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/bitbucket.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type BitbucketRepository = {\n uuid: string;\n name: string;\n full_name: string;\n slug: string;\n mainbranch?: {\n name: string;\n type: string;\n };\n links: {\n html: {\n href: string;\n };\n };\n workspace: {\n slug: string;\n name: string;\n uuid: string;\n };\n owner: {\n display_name: string;\n username?: string;\n uuid: string;\n };\n updated_on: string;\n is_private: boolean;\n};\n\nexport type BitbucketAuthCallbackBody = {\n code: string;\n};\n\nexport type BitbucketAuthCallbackResult = {\n data: {\n token: string;\n };\n};\n\nexport type BitbucketListReposResult = {\n data: BitbucketRepository[];\n};\n\nexport type BitbucketCheckConfigBody = {\n token?: string;\n workspace: string;\n repoSlug: string;\n branch?: string;\n};\n\nexport type BitbucketCheckConfigResult = {\n data: {\n hasConfig: boolean;\n configPaths: string[];\n };\n};\n\nexport type BitbucketGetConfigFileBody = {\n token?: string;\n workspace: string;\n repoSlug: string;\n branch?: string;\n path?: string;\n};\n\nexport type BitbucketGetConfigFileResult = {\n data: {\n content: string;\n };\n};\n\nexport type BitbucketGetAuthUrlResult = {\n data: {\n authUrl: string;\n };\n};\n\nexport const getBitbucketAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const BITBUCKET_API_ROUTE = `${backendURL}/api/bitbucket`;\n\n /**\n * Get Bitbucket OAuth authorization URL\n * @param redirectUri - Redirect URI after OAuth authorization\n */\n const getAuthUrl = async (\n redirectUri: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketGetAuthUrlResult>(\n `${BITBUCKET_API_ROUTE}/auth-url`,\n authAPIOptions,\n otherOptions,\n {\n params: { redirectUri },\n }\n );\n\n /**\n * Exchange Bitbucket authorization code for access token\n * @param code - Bitbucket authorization code\n */\n const authenticate = async (\n code: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketAuthCallbackResult>(\n `${BITBUCKET_API_ROUTE}/auth`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { code },\n }\n );\n\n /**\n * Get user's Bitbucket repositories\n * @param token - Optional Bitbucket access token. If not provided, backend will use session.\n */\n const getRepositories = async (\n token?: string | null,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketListReposResult>(\n `${BITBUCKET_API_ROUTE}/repos`,\n authAPIOptions,\n otherOptions,\n {\n params: token ? { token } : undefined,\n }\n );\n\n /**\n * Check if intlayer.config.ts exists in a Bitbucket repository\n * @param token - Optional Bitbucket access token. If not provided, backend will use session.\n * @param workspace - Bitbucket workspace slug\n * @param repoSlug - Repository slug\n * @param branch - Branch name (default: 'main')\n */\n const checkIntlayerConfig = async (\n token: string | null | undefined,\n workspace: string,\n repoSlug: string,\n branch: string = 'main',\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketCheckConfigResult>(\n `${BITBUCKET_API_ROUTE}/check-config`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { token: token ?? undefined, workspace, repoSlug, branch },\n }\n );\n\n /**\n * Get intlayer.config.ts file contents from a Bitbucket repository\n * @param token - Optional Bitbucket access token. If not provided, backend will use session.\n * @param workspace - Bitbucket workspace slug\n * @param repoSlug - Repository slug\n * @param branch - Branch name (default: 'main')\n * @param path - File path (default: 'intlayer.config.ts')\n */\n const getConfigFile = async (\n token: string | null | undefined,\n workspace: string,\n repoSlug: string,\n branch: string = 'main',\n path: string = 'intlayer.config.ts',\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<BitbucketGetConfigFileResult>(\n `${BITBUCKET_API_ROUTE}/get-config-file`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: {\n token: token ?? undefined,\n workspace,\n repoSlug,\n branch,\n path,\n },\n }\n );\n\n return {\n getAuthUrl,\n authenticate,\n getRepositories,\n checkIntlayerConfig,\n getConfigFile,\n };\n};\n\n/**\n * Authenticated `bitbucket` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const bitbucketEndpoint = createEndpoint(getBitbucketAPI);\n"],"mappings":";;;;;;AAiFA,MAAa,mBACX,iBAAiC,CAAC,GAClC,mBACG;CAGH,MAAM,sBAAsB,GAFT,gBAAgB,QAAQ,cAAcA,8BAAO,WAEtB;;;;;CAM1C,MAAM,aAAa,OACjB,aACA,eAA+B,CAAC,MAEhC,MAAMC,wBACJ,GAAG,oBAAoB,YACvB,gBACA,cACA,EACE,QAAQ,EAAE,YAAY,EACxB,CACF;;;;;CAMF,MAAM,eAAe,OACnB,MACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,oBAAoB,QACvB,gBACA,cACA;EACE,QAAQ;EACR,MAAM,EAAE,KAAK;CACf,CACF;;;;;CAMF,MAAM,kBAAkB,OACtB,OACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,oBAAoB,SACvB,gBACA,cACA,EACE,QAAQ,QAAQ,EAAE,MAAM,IAAI,OAC9B,CACF;;;;;;;;CASF,MAAM,sBAAsB,OAC1B,OACA,WACA,UACA,SAAiB,QACjB,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,oBAAoB,gBACvB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GAAE,OAAO,SAAS;GAAW;GAAW;GAAU;EAAO;CACjE,CACF;;;;;;;;;CAUF,MAAM,gBAAgB,OACpB,OACA,WACA,UACA,SAAiB,QACjB,OAAe,sBACf,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,oBAAoB,mBACvB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GACJ,OAAO,SAAS;GAChB;GACA;GACA;GACA;EACF;CACF,CACF;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;;AAQA,MAAa,oBAAoBC,6CAAe,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"dictionary.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/dictionary.ts"],"sourcesContent":["import type {\n AddDictionaryBody,\n AddDictionaryResult,\n DeleteDictionaryParam,\n DeleteDictionaryResult,\n GetDictionariesKeysResult,\n GetDictionariesParams,\n GetDictionariesResult,\n GetDictionariesUpdateTimestampResult,\n GetDictionaryParams,\n GetDictionaryQuery,\n GetDictionaryResult,\n PushDictionariesBody,\n PushDictionariesResult,\n UpdateDictionaryBody,\n UpdateDictionaryResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getDictionaryAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const PROJECT_API_ROUTE = `${backendURL}/api/dictionary`;\n\n /**\n * Retrieves a list of dictionaries based on filters and pagination.\n * @param filters - Filters and pagination options.\n */\n const getDictionaries = async (\n filters?: GetDictionariesParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetDictionariesResult>(\n PROJECT_API_ROUTE,\n authAPIOptions,\n otherOptions,\n {\n cache: 'no-store',\n // @ts-ignore Number of parameter will be stringified by the fetcher\n params: filters,\n }\n );\n\n /**\n * Retrieves a list of dictionary keys related to the project.\n */\n const getDictionariesKeys = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GetDictionariesKeysResult>(\n `${PROJECT_API_ROUTE}/keys`,\n authAPIOptions,\n otherOptions,\n {\n cache: 'no-store',\n }\n );\n\n /**\n * Retrieves a list of dictionary keys related to the project.\n */\n const getDictionariesUpdateTimestamp = async (\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetDictionariesUpdateTimestampResult>(\n `${PROJECT_API_ROUTE}/update`,\n authAPIOptions,\n otherOptions,\n {\n cache: 'no-store',\n }\n );\n\n /**\n * Retrieves a dictionary by its key and version.\n * @param dictionaryKey - Dictionary key.\n * @param version - Dictionary version of content.\n */\n const getDictionary = async (\n dictionaryKey: GetDictionaryParams['dictionaryKey'],\n version?: GetDictionaryQuery['version'],\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetDictionaryResult>(\n `${PROJECT_API_ROUTE}/${dictionaryKey}`,\n authAPIOptions,\n otherOptions,\n {\n params: version ? { version: version.toString() } : undefined,\n }\n );\n\n /**\n * Adds a new dictionary to the database.\n * @param dictionary - Dictionary data.\n */\n const addDictionary = async (\n body: AddDictionaryBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AddDictionaryResult>(\n `${PROJECT_API_ROUTE}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body,\n }\n );\n\n const pushDictionaries = async (\n dictionaries: PushDictionariesBody['dictionaries'],\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<PushDictionariesResult>(\n `${PROJECT_API_ROUTE}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'PATCH',\n body: { dictionaries },\n }\n );\n\n /**\n * Updates an existing dictionary in the database.\n * @param dictionary - Updated dictionary data.\n */\n const updateDictionary = async (\n dictionary: UpdateDictionaryBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<UpdateDictionaryResult>(\n `${PROJECT_API_ROUTE}/${dictionary.id}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'PUT',\n body: dictionary,\n }\n );\n\n /**\n * Deletes a dictionary from the database by its ID.\n * @param id - Dictionary ID.\n */\n const deleteDictionary = async (\n id: DeleteDictionaryParam['dictionaryId'],\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<DeleteDictionaryResult>(\n `${PROJECT_API_ROUTE}/${id}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'DELETE',\n }\n );\n\n return {\n getDictionaries,\n getDictionariesKeys,\n getDictionariesUpdateTimestamp,\n getDictionary,\n pushDictionaries,\n addDictionary,\n updateDictionary,\n deleteDictionary,\n };\n};\n\n/**\n * Authenticated `dictionary` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const dictionaryEndpoint = createEndpoint(getDictionaryAPI);\n"],"mappings":";;;;;;AAsBA,MAAa,oBACX,iBAAiC,EAAE,EACnC,mBACG;CAGH,MAAM,oBAAoB,GAFP,gBAAgB,QAAQ,cAAcA,8BAAO,WAExB;;;;;CAMxC,MAAM,kBAAkB,OACtB,SACA,eAA+B,EAAE,KAEjC,MAAMC,wBACJ,mBACA,gBACA,cACA;EACE,OAAO;EAEP,QAAQ;EACT,CACF;;;;CAKH,MAAM,sBAAsB,OAAO,eAA+B,EAAE,KAClE,MAAMA,wBACJ,GAAG,kBAAkB,QACrB,gBACA,cACA,EACE,OAAO,YACR,CACF;;;;CAKH,MAAM,iCAAiC,OACrC,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,kBAAkB,UACrB,gBACA,cACA,EACE,OAAO,YACR,CACF;;;;;;CAOH,MAAM,gBAAgB,OACpB,eACA,SACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,kBAAkB,GAAG,iBACxB,gBACA,cACA,EACE,QAAQ,UAAU,EAAE,SAAS,QAAQ,UAAU,EAAE,GAAG,QACrD,CACF;;;;;CAMH,MAAM,gBAAgB,OACpB,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,qBACH,gBACA,cACA;EACE,QAAQ;EACR;EACD,CACF;CAEH,MAAM,mBAAmB,OACvB,cACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,qBACH,gBACA,cACA;EACE,QAAQ;EACR,MAAM,EAAE,cAAc;EACvB,CACF;;;;;CAMH,MAAM,mBAAmB,OACvB,YACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,kBAAkB,GAAG,WAAW,MACnC,gBACA,cACA;EACE,QAAQ;EACR,MAAM;EACP,CACF;;;;;CAMH,MAAM,mBAAmB,OACvB,IACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,kBAAkB,GAAG,MACxB,gBACA,cACA,EACE,QAAQ,UACT,CACF;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;;;;;;;AASH,MAAa,qBAAqBC,6CAAe,iBAAiB"}
1
+ {"version":3,"file":"dictionary.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/dictionary.ts"],"sourcesContent":["import type {\n AddDictionaryBody,\n AddDictionaryResult,\n DeleteDictionaryParam,\n DeleteDictionaryResult,\n GetDictionariesKeysResult,\n GetDictionariesParams,\n GetDictionariesResult,\n GetDictionariesUpdateTimestampResult,\n GetDictionaryParams,\n GetDictionaryQuery,\n GetDictionaryResult,\n PushDictionariesBody,\n PushDictionariesResult,\n UpdateDictionaryBody,\n UpdateDictionaryResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getDictionaryAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const PROJECT_API_ROUTE = `${backendURL}/api/dictionary`;\n\n /**\n * Retrieves a list of dictionaries based on filters and pagination.\n * @param filters - Filters and pagination options.\n */\n const getDictionaries = async (\n filters?: GetDictionariesParams,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetDictionariesResult>(\n PROJECT_API_ROUTE,\n authAPIOptions,\n otherOptions,\n {\n cache: 'no-store',\n // @ts-ignore Number of parameter will be stringified by the fetcher\n params: filters,\n }\n );\n\n /**\n * Retrieves a list of dictionary keys related to the project.\n */\n const getDictionariesKeys = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GetDictionariesKeysResult>(\n `${PROJECT_API_ROUTE}/keys`,\n authAPIOptions,\n otherOptions,\n {\n cache: 'no-store',\n }\n );\n\n /**\n * Retrieves a list of dictionary keys related to the project.\n */\n const getDictionariesUpdateTimestamp = async (\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetDictionariesUpdateTimestampResult>(\n `${PROJECT_API_ROUTE}/update`,\n authAPIOptions,\n otherOptions,\n {\n cache: 'no-store',\n }\n );\n\n /**\n * Retrieves a dictionary by its key and version.\n * @param dictionaryKey - Dictionary key.\n * @param version - Dictionary version of content.\n */\n const getDictionary = async (\n dictionaryKey: GetDictionaryParams['dictionaryKey'],\n version?: GetDictionaryQuery['version'],\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GetDictionaryResult>(\n `${PROJECT_API_ROUTE}/${dictionaryKey}`,\n authAPIOptions,\n otherOptions,\n {\n params: version ? { version: version.toString() } : undefined,\n }\n );\n\n /**\n * Adds a new dictionary to the database.\n * @param dictionary - Dictionary data.\n */\n const addDictionary = async (\n body: AddDictionaryBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AddDictionaryResult>(\n `${PROJECT_API_ROUTE}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body,\n }\n );\n\n const pushDictionaries = async (\n dictionaries: PushDictionariesBody['dictionaries'],\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<PushDictionariesResult>(\n `${PROJECT_API_ROUTE}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'PATCH',\n body: { dictionaries },\n }\n );\n\n /**\n * Updates an existing dictionary in the database.\n * @param dictionary - Updated dictionary data.\n */\n const updateDictionary = async (\n dictionary: UpdateDictionaryBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<UpdateDictionaryResult>(\n `${PROJECT_API_ROUTE}/${dictionary.id}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'PUT',\n body: dictionary,\n }\n );\n\n /**\n * Deletes a dictionary from the database by its ID.\n * @param id - Dictionary ID.\n */\n const deleteDictionary = async (\n id: DeleteDictionaryParam['dictionaryId'],\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<DeleteDictionaryResult>(\n `${PROJECT_API_ROUTE}/${id}`,\n authAPIOptions,\n otherOptions,\n {\n method: 'DELETE',\n }\n );\n\n return {\n getDictionaries,\n getDictionariesKeys,\n getDictionariesUpdateTimestamp,\n getDictionary,\n pushDictionaries,\n addDictionary,\n updateDictionary,\n deleteDictionary,\n };\n};\n\n/**\n * Authenticated `dictionary` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const dictionaryEndpoint = createEndpoint(getDictionaryAPI);\n"],"mappings":";;;;;;AAsBA,MAAa,oBACX,iBAAiC,CAAC,GAClC,mBACG;CAGH,MAAM,oBAAoB,GAFP,gBAAgB,QAAQ,cAAcA,8BAAO,WAExB;;;;;CAMxC,MAAM,kBAAkB,OACtB,SACA,eAA+B,CAAC,MAEhC,MAAMC,wBACJ,mBACA,gBACA,cACA;EACE,OAAO;EAEP,QAAQ;CACV,CACF;;;;CAKF,MAAM,sBAAsB,OAAO,eAA+B,CAAC,MACjE,MAAMA,wBACJ,GAAG,kBAAkB,QACrB,gBACA,cACA,EACE,OAAO,WACT,CACF;;;;CAKF,MAAM,iCAAiC,OACrC,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,kBAAkB,UACrB,gBACA,cACA,EACE,OAAO,WACT,CACF;;;;;;CAOF,MAAM,gBAAgB,OACpB,eACA,SACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,kBAAkB,GAAG,iBACxB,gBACA,cACA,EACE,QAAQ,UAAU,EAAE,SAAS,QAAQ,SAAS,EAAE,IAAI,OACtD,CACF;;;;;CAMF,MAAM,gBAAgB,OACpB,MACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,qBACH,gBACA,cACA;EACE,QAAQ;EACR;CACF,CACF;CAEF,MAAM,mBAAmB,OACvB,cACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,qBACH,gBACA,cACA;EACE,QAAQ;EACR,MAAM,EAAE,aAAa;CACvB,CACF;;;;;CAMF,MAAM,mBAAmB,OACvB,YACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,kBAAkB,GAAG,WAAW,MACnC,gBACA,cACA;EACE,QAAQ;EACR,MAAM;CACR,CACF;;;;;CAMF,MAAM,mBAAmB,OACvB,IACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,kBAAkB,GAAG,MACxB,gBACA,cACA,EACE,QAAQ,SACV,CACF;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;;AAQA,MAAa,qBAAqBC,6CAAe,gBAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"editor.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/editor.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type {\n GetConfigurationResult,\n GetEditorDictionariesResult,\n WriteContentDeclarationBody,\n WriteContentDeclarationResult,\n} from 'intlayer-editor';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getEditorAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const editorURL = intlayerConfig?.editor?.editorURL ?? editor.editorURL;\n\n const EDITOR_API_ROUTE = `${editorURL}/api`;\n\n /**\n * Get the Intlayer configuration\n */\n const getConfiguration = async (\n otherOptions: FetcherOptions = {}\n ): Promise<GetConfigurationResult> => {\n const response = await fetcher<GetConfigurationResult>(\n `${EDITOR_API_ROUTE}/config`,\n authAPIOptions,\n otherOptions\n );\n\n return response.data as unknown as GetConfigurationResult;\n };\n\n /**\n * Get the Intlayer configuration\n */\n const getDictionaries = async (\n otherOptions: FetcherOptions = {}\n ): Promise<GetEditorDictionariesResult> => {\n const response = await fetcher<GetEditorDictionariesResult>(\n `${EDITOR_API_ROUTE}/dictionary`,\n authAPIOptions,\n otherOptions\n );\n\n return response.data as unknown as GetEditorDictionariesResult;\n };\n\n /**\n * Adds a new dictionary to the database.\n * @param dictionary - Dictionary data.\n */\n const writeDictionary = async (\n body: WriteContentDeclarationBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<WriteContentDeclarationResult>(\n `${EDITOR_API_ROUTE}/dictionary`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body,\n }\n );\n\n return {\n getDictionaries,\n getConfiguration,\n writeDictionary,\n };\n};\n\n/**\n * Authenticated `editor` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const editorEndpoint = createEndpoint(getEditorAPI);\n"],"mappings":";;;;;;AAWA,MAAa,gBACX,iBAAiC,EAAE,EACnC,mBACG;CAGH,MAAM,mBAAmB,GAFP,gBAAgB,QAAQ,aAAaA,8BAAO,UAExB;;;;CAKtC,MAAM,mBAAmB,OACvB,eAA+B,EAAE,KACG;AAOpC,UAAO,MANgBC,wBACrB,GAAG,iBAAiB,UACpB,gBACA,aACD,EAEe;;;;;CAMlB,MAAM,kBAAkB,OACtB,eAA+B,EAAE,KACQ;AAOzC,UAAO,MANgBA,wBACrB,GAAG,iBAAiB,cACpB,gBACA,aACD,EAEe;;;;;;CAOlB,MAAM,kBAAkB,OACtB,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,iBAAiB,cACpB,gBACA,cACA;EACE,QAAQ;EACR;EACD,CACF;AAEH,QAAO;EACL;EACA;EACA;EACD;;;;;;;;AASH,MAAa,iBAAiBC,6CAAe,aAAa"}
1
+ {"version":3,"file":"editor.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/editor.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type {\n GetConfigurationResult,\n GetEditorDictionariesResult,\n WriteContentDeclarationBody,\n WriteContentDeclarationResult,\n} from 'intlayer-editor';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getEditorAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const editorURL = intlayerConfig?.editor?.editorURL ?? editor.editorURL;\n\n const EDITOR_API_ROUTE = `${editorURL}/api`;\n\n /**\n * Get the Intlayer configuration\n */\n const getConfiguration = async (\n otherOptions: FetcherOptions = {}\n ): Promise<GetConfigurationResult> => {\n const response = await fetcher<GetConfigurationResult>(\n `${EDITOR_API_ROUTE}/config`,\n authAPIOptions,\n otherOptions\n );\n\n return response.data as unknown as GetConfigurationResult;\n };\n\n /**\n * Get the Intlayer configuration\n */\n const getDictionaries = async (\n otherOptions: FetcherOptions = {}\n ): Promise<GetEditorDictionariesResult> => {\n const response = await fetcher<GetEditorDictionariesResult>(\n `${EDITOR_API_ROUTE}/dictionary`,\n authAPIOptions,\n otherOptions\n );\n\n return response.data as unknown as GetEditorDictionariesResult;\n };\n\n /**\n * Adds a new dictionary to the database.\n * @param dictionary - Dictionary data.\n */\n const writeDictionary = async (\n body: WriteContentDeclarationBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<WriteContentDeclarationResult>(\n `${EDITOR_API_ROUTE}/dictionary`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body,\n }\n );\n\n return {\n getDictionaries,\n getConfiguration,\n writeDictionary,\n };\n};\n\n/**\n * Authenticated `editor` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const editorEndpoint = createEndpoint(getEditorAPI);\n"],"mappings":";;;;;;AAWA,MAAa,gBACX,iBAAiC,CAAC,GAClC,mBACG;CAGH,MAAM,mBAAmB,GAFP,gBAAgB,QAAQ,aAAaA,8BAAO,UAExB;;;;CAKtC,MAAM,mBAAmB,OACvB,eAA+B,CAAC,MACI;EAOpC,QAAO,MANgBC,wBACrB,GAAG,iBAAiB,UACpB,gBACA,YACF,EAEe,CAAC;CAClB;;;;CAKA,MAAM,kBAAkB,OACtB,eAA+B,CAAC,MACS;EAOzC,QAAO,MANgBA,wBACrB,GAAG,iBAAiB,cACpB,gBACA,YACF,EAEe,CAAC;CAClB;;;;;CAMA,MAAM,kBAAkB,OACtB,MACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,iBAAiB,cACpB,gBACA,cACA;EACE,QAAQ;EACR;CACF,CACF;CAEF,OAAO;EACL;EACA;EACA;CACF;AACF;;;;;;;AAQA,MAAa,iBAAiBC,6CAAe,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"environment.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/environment.ts"],"sourcesContent":["import type {\n AddEnvironmentBody,\n AddEnvironmentResult,\n DeleteEnvironmentResult,\n MigrateEnvironmentBody,\n MigrateEnvironmentResult,\n ResetToProductionEnvironmentResult,\n SelectEnvironmentResult,\n UpdateEnvironmentBody,\n UpdateEnvironmentResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getEnvironmentAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n const ENVIRONMENT_API_ROUTE = `${backendURL}/api/project/environment`;\n\n const addEnvironment = async (\n body: AddEnvironmentBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AddEnvironmentResult>(\n ENVIRONMENT_API_ROUTE,\n authAPIOptions,\n otherOptions,\n { method: 'POST', body }\n );\n\n const updateEnvironment = async (\n environmentId: string,\n body: UpdateEnvironmentBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<UpdateEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/${environmentId}`,\n authAPIOptions,\n otherOptions,\n { method: 'PUT', body }\n );\n\n const deleteEnvironment = async (\n environmentId: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<DeleteEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/${environmentId}`,\n authAPIOptions,\n otherOptions,\n { method: 'DELETE' }\n );\n\n const selectEnvironment = async (\n environmentId: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<SelectEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/${environmentId}/select`,\n authAPIOptions,\n otherOptions,\n { method: 'PUT' }\n );\n\n const resetToProductionEnvironment = async (\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<ResetToProductionEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/production/select`,\n authAPIOptions,\n otherOptions,\n { method: 'PUT' }\n );\n\n const migrateEnvironment = async (\n body: MigrateEnvironmentBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<MigrateEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/migrate`,\n authAPIOptions,\n otherOptions,\n { method: 'POST', body }\n );\n\n return {\n addEnvironment,\n updateEnvironment,\n deleteEnvironment,\n selectEnvironment,\n resetToProductionEnvironment,\n migrateEnvironment,\n };\n};\n\n/**\n * Authenticated `environment` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const environmentEndpoint = createEndpoint(getEnvironmentAPI);\n"],"mappings":";;;;;;AAgBA,MAAa,qBACX,iBAAiC,EAAE,EACnC,mBACG;CAEH,MAAM,wBAAwB,GADX,gBAAgB,QAAQ,cAAcA,8BAAO,WACpB;CAE5C,MAAM,iBAAiB,OACrB,MACA,eAA+B,EAAE,KAEjC,MAAMC,wBACJ,uBACA,gBACA,cACA;EAAE,QAAQ;EAAQ;EAAM,CACzB;CAEH,MAAM,oBAAoB,OACxB,eACA,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,sBAAsB,GAAG,iBAC5B,gBACA,cACA;EAAE,QAAQ;EAAO;EAAM,CACxB;CAEH,MAAM,oBAAoB,OACxB,eACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,sBAAsB,GAAG,iBAC5B,gBACA,cACA,EAAE,QAAQ,UAAU,CACrB;CAEH,MAAM,oBAAoB,OACxB,eACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,sBAAsB,GAAG,cAAc,UAC1C,gBACA,cACA,EAAE,QAAQ,OAAO,CAClB;CAEH,MAAM,+BAA+B,OACnC,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,sBAAsB,qBACzB,gBACA,cACA,EAAE,QAAQ,OAAO,CAClB;CAEH,MAAM,qBAAqB,OACzB,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,sBAAsB,WACzB,gBACA,cACA;EAAE,QAAQ;EAAQ;EAAM,CACzB;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD;;;;;;;;AASH,MAAa,sBAAsBC,6CAAe,kBAAkB"}
1
+ {"version":3,"file":"environment.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/environment.ts"],"sourcesContent":["import type {\n AddEnvironmentBody,\n AddEnvironmentResult,\n DeleteEnvironmentResult,\n MigrateEnvironmentBody,\n MigrateEnvironmentResult,\n ResetToProductionEnvironmentResult,\n SelectEnvironmentResult,\n UpdateEnvironmentBody,\n UpdateEnvironmentResult,\n} from '@intlayer/backend';\nimport { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport const getEnvironmentAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n const ENVIRONMENT_API_ROUTE = `${backendURL}/api/project/environment`;\n\n const addEnvironment = async (\n body: AddEnvironmentBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<AddEnvironmentResult>(\n ENVIRONMENT_API_ROUTE,\n authAPIOptions,\n otherOptions,\n { method: 'POST', body }\n );\n\n const updateEnvironment = async (\n environmentId: string,\n body: UpdateEnvironmentBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<UpdateEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/${environmentId}`,\n authAPIOptions,\n otherOptions,\n { method: 'PUT', body }\n );\n\n const deleteEnvironment = async (\n environmentId: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<DeleteEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/${environmentId}`,\n authAPIOptions,\n otherOptions,\n { method: 'DELETE' }\n );\n\n const selectEnvironment = async (\n environmentId: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<SelectEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/${environmentId}/select`,\n authAPIOptions,\n otherOptions,\n { method: 'PUT' }\n );\n\n const resetToProductionEnvironment = async (\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<ResetToProductionEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/production/select`,\n authAPIOptions,\n otherOptions,\n { method: 'PUT' }\n );\n\n const migrateEnvironment = async (\n body: MigrateEnvironmentBody,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<MigrateEnvironmentResult>(\n `${ENVIRONMENT_API_ROUTE}/migrate`,\n authAPIOptions,\n otherOptions,\n { method: 'POST', body }\n );\n\n return {\n addEnvironment,\n updateEnvironment,\n deleteEnvironment,\n selectEnvironment,\n resetToProductionEnvironment,\n migrateEnvironment,\n };\n};\n\n/**\n * Authenticated `environment` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const environmentEndpoint = createEndpoint(getEnvironmentAPI);\n"],"mappings":";;;;;;AAgBA,MAAa,qBACX,iBAAiC,CAAC,GAClC,mBACG;CAEH,MAAM,wBAAwB,GADX,gBAAgB,QAAQ,cAAcA,8BAAO,WACpB;CAE5C,MAAM,iBAAiB,OACrB,MACA,eAA+B,CAAC,MAEhC,MAAMC,wBACJ,uBACA,gBACA,cACA;EAAE,QAAQ;EAAQ;CAAK,CACzB;CAEF,MAAM,oBAAoB,OACxB,eACA,MACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,sBAAsB,GAAG,iBAC5B,gBACA,cACA;EAAE,QAAQ;EAAO;CAAK,CACxB;CAEF,MAAM,oBAAoB,OACxB,eACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,sBAAsB,GAAG,iBAC5B,gBACA,cACA,EAAE,QAAQ,SAAS,CACrB;CAEF,MAAM,oBAAoB,OACxB,eACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,sBAAsB,GAAG,cAAc,UAC1C,gBACA,cACA,EAAE,QAAQ,MAAM,CAClB;CAEF,MAAM,+BAA+B,OACnC,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,sBAAsB,qBACzB,gBACA,cACA,EAAE,QAAQ,MAAM,CAClB;CAEF,MAAM,qBAAqB,OACzB,MACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,sBAAsB,WACzB,gBACA,cACA;EAAE,QAAQ;EAAQ;CAAK,CACzB;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;;AAQA,MAAa,sBAAsBC,6CAAe,iBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"github.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/github.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type GitHubRepository = {\n id: number;\n name: string;\n full_name: string;\n owner: {\n login: string;\n id: number;\n };\n html_url: string;\n default_branch: string;\n private: boolean;\n};\n\nexport type GitHubAuthCallbackBody = {\n code: string;\n};\n\nexport type GitHubAuthCallbackResult = {\n data: {\n token: string;\n };\n};\n\nexport type GitHubListReposResult = {\n data: GitHubRepository[];\n};\n\nexport type GitHubCheckConfigBody = {\n token?: string;\n owner: string;\n repository: string;\n branch?: string;\n};\n\nexport type GitHubCheckConfigResult = {\n data: {\n hasConfig: boolean;\n };\n};\n\nexport type GitHubGetConfigFileBody = {\n token?: string;\n owner: string;\n repository: string;\n branch?: string;\n path?: string;\n};\n\nexport type GitHubGetConfigFileResult = {\n data: {\n content: string;\n };\n};\n\nexport type GitHubGetAuthUrlResult = {\n data: {\n authUrl: string;\n };\n};\n\nexport type GitHubGetTokenResult = {\n data: {\n token: string;\n };\n};\n\nexport const getGithubAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const GITHUB_API_ROUTE = `${backendURL}/api/github`;\n\n /**\n * Get GitHub OAuth authorization URL\n * @param redirectUri - Redirect URI after OAuth authorization\n */\n const getAuthUrl = async (\n redirectUri: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubGetAuthUrlResult>(\n `${GITHUB_API_ROUTE}/auth-url`,\n authAPIOptions,\n otherOptions,\n {\n params: { redirectUri },\n }\n );\n\n /**\n * Exchange GitHub authorization code for access token\n * @param code - GitHub authorization code\n */\n const authenticate = async (\n code: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubAuthCallbackResult>(\n `${GITHUB_API_ROUTE}/auth`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { code },\n }\n );\n\n /**\n * Get user's GitHub repositories\n * @param token - Optional GitHub access token. If not provided, backend will use session.\n */\n const getRepositories = async (\n token?: string | null,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubListReposResult>(\n `${GITHUB_API_ROUTE}/repos`,\n authAPIOptions,\n otherOptions,\n {\n params: token ? { token } : undefined,\n }\n );\n\n /**\n * Check if intlayer.config.ts exists in a repository\n * @param token - Optional GitHub access token. If not provided, backend will use session.\n * @param owner - Repository owner\n * @param repository - Repository name\n * @param branch - Branch name (default: 'main')\n */\n const checkIntlayerConfig = async (\n token: string | null | undefined,\n owner: string,\n repository: string,\n branch: string = 'main',\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubCheckConfigResult>(\n `${GITHUB_API_ROUTE}/check-config`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { token: token ?? undefined, owner, repository, branch },\n }\n );\n\n /**\n * Get intlayer.config.ts file contents from a repository\n * @param token - Optional GitHub access token. If not provided, backend will use session.\n * @param owner - Repository owner\n * @param repository - Repository name\n * @param branch - Branch name (default: 'main')\n * @param path - File path (default: 'intlayer.config.ts')\n */\n const getConfigFile = async (\n token: string | null | undefined,\n owner: string,\n repository: string,\n branch: string = 'main',\n path: string = 'intlayer.config.ts',\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubGetConfigFileResult>(\n `${GITHUB_API_ROUTE}/get-config-file`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { token: token ?? undefined, owner, repository, branch, path },\n }\n );\n\n /**\n * Get user's GitHub token\n */\n const getToken = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GitHubGetTokenResult>(\n `${GITHUB_API_ROUTE}/token`,\n authAPIOptions,\n otherOptions\n );\n\n return {\n getAuthUrl,\n authenticate,\n getRepositories,\n checkIntlayerConfig,\n getConfigFile,\n getToken,\n };\n};\n\n/**\n * Authenticated `github` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const githubEndpoint = createEndpoint(getGithubAPI);\n"],"mappings":";;;;;;AAuEA,MAAa,gBACX,iBAAiC,EAAE,EACnC,mBACG;CAGH,MAAM,mBAAmB,GAFN,gBAAgB,QAAQ,cAAcA,8BAAO,WAEzB;;;;;CAMvC,MAAM,aAAa,OACjB,aACA,eAA+B,EAAE,KAEjC,MAAMC,wBACJ,GAAG,iBAAiB,YACpB,gBACA,cACA,EACE,QAAQ,EAAE,aAAa,EACxB,CACF;;;;;CAMH,MAAM,eAAe,OACnB,MACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,iBAAiB,QACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM,EAAE,MAAM;EACf,CACF;;;;;CAMH,MAAM,kBAAkB,OACtB,OACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,iBAAiB,SACpB,gBACA,cACA,EACE,QAAQ,QAAQ,EAAE,OAAO,GAAG,QAC7B,CACF;;;;;;;;CASH,MAAM,sBAAsB,OAC1B,OACA,OACA,YACA,SAAiB,QACjB,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,iBAAiB,gBACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GAAE,OAAO,SAAS;GAAW;GAAO;GAAY;GAAQ;EAC/D,CACF;;;;;;;;;CAUH,MAAM,gBAAgB,OACpB,OACA,OACA,YACA,SAAiB,QACjB,OAAe,sBACf,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,iBAAiB,mBACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GAAE,OAAO,SAAS;GAAW;GAAO;GAAY;GAAQ;GAAM;EACrE,CACF;;;;CAKH,MAAM,WAAW,OAAO,eAA+B,EAAE,KACvD,MAAMA,wBACJ,GAAG,iBAAiB,SACpB,gBACA,aACD;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD;;;;;;;;AASH,MAAa,iBAAiBC,6CAAe,aAAa"}
1
+ {"version":3,"file":"github.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/github.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type GitHubRepository = {\n id: number;\n name: string;\n full_name: string;\n owner: {\n login: string;\n id: number;\n };\n html_url: string;\n default_branch: string;\n private: boolean;\n};\n\nexport type GitHubAuthCallbackBody = {\n code: string;\n};\n\nexport type GitHubAuthCallbackResult = {\n data: {\n token: string;\n };\n};\n\nexport type GitHubListReposResult = {\n data: GitHubRepository[];\n};\n\nexport type GitHubCheckConfigBody = {\n token?: string;\n owner: string;\n repository: string;\n branch?: string;\n};\n\nexport type GitHubCheckConfigResult = {\n data: {\n hasConfig: boolean;\n };\n};\n\nexport type GitHubGetConfigFileBody = {\n token?: string;\n owner: string;\n repository: string;\n branch?: string;\n path?: string;\n};\n\nexport type GitHubGetConfigFileResult = {\n data: {\n content: string;\n };\n};\n\nexport type GitHubGetAuthUrlResult = {\n data: {\n authUrl: string;\n };\n};\n\nexport type GitHubGetTokenResult = {\n data: {\n token: string;\n };\n};\n\nexport const getGithubAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const GITHUB_API_ROUTE = `${backendURL}/api/github`;\n\n /**\n * Get GitHub OAuth authorization URL\n * @param redirectUri - Redirect URI after OAuth authorization\n */\n const getAuthUrl = async (\n redirectUri: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubGetAuthUrlResult>(\n `${GITHUB_API_ROUTE}/auth-url`,\n authAPIOptions,\n otherOptions,\n {\n params: { redirectUri },\n }\n );\n\n /**\n * Exchange GitHub authorization code for access token\n * @param code - GitHub authorization code\n */\n const authenticate = async (\n code: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubAuthCallbackResult>(\n `${GITHUB_API_ROUTE}/auth`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { code },\n }\n );\n\n /**\n * Get user's GitHub repositories\n * @param token - Optional GitHub access token. If not provided, backend will use session.\n */\n const getRepositories = async (\n token?: string | null,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubListReposResult>(\n `${GITHUB_API_ROUTE}/repos`,\n authAPIOptions,\n otherOptions,\n {\n params: token ? { token } : undefined,\n }\n );\n\n /**\n * Check if intlayer.config.ts exists in a repository\n * @param token - Optional GitHub access token. If not provided, backend will use session.\n * @param owner - Repository owner\n * @param repository - Repository name\n * @param branch - Branch name (default: 'main')\n */\n const checkIntlayerConfig = async (\n token: string | null | undefined,\n owner: string,\n repository: string,\n branch: string = 'main',\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubCheckConfigResult>(\n `${GITHUB_API_ROUTE}/check-config`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { token: token ?? undefined, owner, repository, branch },\n }\n );\n\n /**\n * Get intlayer.config.ts file contents from a repository\n * @param token - Optional GitHub access token. If not provided, backend will use session.\n * @param owner - Repository owner\n * @param repository - Repository name\n * @param branch - Branch name (default: 'main')\n * @param path - File path (default: 'intlayer.config.ts')\n */\n const getConfigFile = async (\n token: string | null | undefined,\n owner: string,\n repository: string,\n branch: string = 'main',\n path: string = 'intlayer.config.ts',\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitHubGetConfigFileResult>(\n `${GITHUB_API_ROUTE}/get-config-file`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { token: token ?? undefined, owner, repository, branch, path },\n }\n );\n\n /**\n * Get user's GitHub token\n */\n const getToken = async (otherOptions: FetcherOptions = {}) =>\n await fetcher<GitHubGetTokenResult>(\n `${GITHUB_API_ROUTE}/token`,\n authAPIOptions,\n otherOptions\n );\n\n return {\n getAuthUrl,\n authenticate,\n getRepositories,\n checkIntlayerConfig,\n getConfigFile,\n getToken,\n };\n};\n\n/**\n * Authenticated `github` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const githubEndpoint = createEndpoint(getGithubAPI);\n"],"mappings":";;;;;;AAuEA,MAAa,gBACX,iBAAiC,CAAC,GAClC,mBACG;CAGH,MAAM,mBAAmB,GAFN,gBAAgB,QAAQ,cAAcA,8BAAO,WAEzB;;;;;CAMvC,MAAM,aAAa,OACjB,aACA,eAA+B,CAAC,MAEhC,MAAMC,wBACJ,GAAG,iBAAiB,YACpB,gBACA,cACA,EACE,QAAQ,EAAE,YAAY,EACxB,CACF;;;;;CAMF,MAAM,eAAe,OACnB,MACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,iBAAiB,QACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM,EAAE,KAAK;CACf,CACF;;;;;CAMF,MAAM,kBAAkB,OACtB,OACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,iBAAiB,SACpB,gBACA,cACA,EACE,QAAQ,QAAQ,EAAE,MAAM,IAAI,OAC9B,CACF;;;;;;;;CASF,MAAM,sBAAsB,OAC1B,OACA,OACA,YACA,SAAiB,QACjB,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,iBAAiB,gBACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GAAE,OAAO,SAAS;GAAW;GAAO;GAAY;EAAO;CAC/D,CACF;;;;;;;;;CAUF,MAAM,gBAAgB,OACpB,OACA,OACA,YACA,SAAiB,QACjB,OAAe,sBACf,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,iBAAiB,mBACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GAAE,OAAO,SAAS;GAAW;GAAO;GAAY;GAAQ;EAAK;CACrE,CACF;;;;CAKF,MAAM,WAAW,OAAO,eAA+B,CAAC,MACtD,MAAMA,wBACJ,GAAG,iBAAiB,SACpB,gBACA,YACF;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;;AAQA,MAAa,iBAAiBC,6CAAe,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"gitlab.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/gitlab.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type GitLabProject = {\n id: number;\n name: string;\n path_with_namespace: string;\n web_url: string;\n default_branch: string;\n visibility: string;\n last_activity_at: string;\n namespace: {\n id: number;\n name: string;\n path: string;\n };\n};\n\nexport type GitLabAuthCallbackBody = {\n code: string;\n redirectUri: string;\n instanceUrl?: string;\n};\n\nexport type GitLabAuthCallbackResult = {\n data: {\n token: string;\n };\n};\n\nexport type GitLabListProjectsResult = {\n data: GitLabProject[];\n};\n\nexport type GitLabCheckConfigBody = {\n token?: string;\n projectId: number;\n branch?: string;\n instanceUrl?: string;\n};\n\nexport type GitLabCheckConfigResult = {\n data: {\n hasConfig: boolean;\n configPaths: string[];\n };\n};\n\nexport type GitLabGetConfigFileBody = {\n token?: string;\n projectId: number;\n branch?: string;\n path?: string;\n instanceUrl?: string;\n};\n\nexport type GitLabGetConfigFileResult = {\n data: {\n content: string;\n };\n};\n\nexport type GitLabGetAuthUrlResult = {\n data: {\n authUrl: string;\n };\n};\n\nexport const getGitlabAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const GITLAB_API_ROUTE = `${backendURL}/api/gitlab`;\n\n /**\n * Get GitLab OAuth authorization URL\n * @param redirectUri - Redirect URI after OAuth authorization\n * @param instanceUrl - Custom GitLab instance URL (optional, for self-hosted)\n */\n const getAuthUrl = async (\n redirectUri: string,\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabGetAuthUrlResult>(\n `${GITLAB_API_ROUTE}/auth-url`,\n authAPIOptions,\n otherOptions,\n {\n params: { redirectUri, ...(instanceUrl && { instanceUrl }) },\n }\n );\n\n /**\n * Exchange GitLab authorization code for access token\n * @param code - GitLab authorization code\n * @param redirectUri - Redirect URI used in the authorization request\n * @param instanceUrl - Custom GitLab instance URL (optional)\n */\n const authenticate = async (\n code: string,\n redirectUri: string,\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabAuthCallbackResult>(\n `${GITLAB_API_ROUTE}/auth`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { code, redirectUri, instanceUrl },\n }\n );\n\n /**\n * Get user's GitLab projects\n * @param token - Optional GitLab access token. If not provided, backend will use session.\n * @param instanceUrl - Custom GitLab instance URL (optional)\n */\n const getProjects = async (\n token?: string | null,\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabListProjectsResult>(\n `${GITLAB_API_ROUTE}/projects`,\n authAPIOptions,\n otherOptions,\n {\n params: {\n ...(token && { token }),\n ...(instanceUrl && { instanceUrl }),\n },\n }\n );\n\n /**\n * Check if intlayer.config.ts exists in a GitLab repository\n * @param token - Optional GitLab access token. If not provided, backend will use session.\n * @param projectId - GitLab project ID\n * @param branch - Branch name (default: 'main')\n * @param instanceUrl - Custom GitLab instance URL (optional)\n */\n const checkIntlayerConfig = async (\n token: string | null | undefined,\n projectId: number,\n branch: string = 'main',\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabCheckConfigResult>(\n `${GITLAB_API_ROUTE}/check-config`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: {\n token: token ?? undefined,\n projectId,\n branch,\n ...(instanceUrl && { instanceUrl }),\n },\n }\n );\n\n /**\n * Get intlayer.config.ts file contents from a GitLab repository\n * @param token - Optional GitLab access token. If not provided, backend will use session.\n * @param projectId - GitLab project ID\n * @param branch - Branch name (default: 'main')\n * @param path - File path (default: 'intlayer.config.ts')\n * @param instanceUrl - Custom GitLab instance URL (optional)\n */\n const getConfigFile = async (\n token: string | null | undefined,\n projectId: number,\n branch: string = 'main',\n path: string = 'intlayer.config.ts',\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabGetConfigFileResult>(\n `${GITLAB_API_ROUTE}/get-config-file`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: {\n token: token ?? undefined,\n projectId,\n branch,\n path,\n ...(instanceUrl && { instanceUrl }),\n },\n }\n );\n\n return {\n getAuthUrl,\n authenticate,\n getProjects,\n checkIntlayerConfig,\n getConfigFile,\n };\n};\n\n/**\n * Authenticated `gitlab` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const gitlabEndpoint = createEndpoint(getGitlabAPI);\n"],"mappings":";;;;;;AAsEA,MAAa,gBACX,iBAAiC,EAAE,EACnC,mBACG;CAGH,MAAM,mBAAmB,GAFN,gBAAgB,QAAQ,cAAcA,8BAAO,WAEzB;;;;;;CAOvC,MAAM,aAAa,OACjB,aACA,aACA,eAA+B,EAAE,KAEjC,MAAMC,wBACJ,GAAG,iBAAiB,YACpB,gBACA,cACA,EACE,QAAQ;EAAE;EAAa,GAAI,eAAe,EAAE,aAAa;EAAG,EAC7D,CACF;;;;;;;CAQH,MAAM,eAAe,OACnB,MACA,aACA,aACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,iBAAiB,QACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GAAE;GAAM;GAAa;GAAa;EACzC,CACF;;;;;;CAOH,MAAM,cAAc,OAClB,OACA,aACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,iBAAiB,YACpB,gBACA,cACA,EACE,QAAQ;EACN,GAAI,SAAS,EAAE,OAAO;EACtB,GAAI,eAAe,EAAE,aAAa;EACnC,EACF,CACF;;;;;;;;CASH,MAAM,sBAAsB,OAC1B,OACA,WACA,SAAiB,QACjB,aACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,iBAAiB,gBACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GACJ,OAAO,SAAS;GAChB;GACA;GACA,GAAI,eAAe,EAAE,aAAa;GACnC;EACF,CACF;;;;;;;;;CAUH,MAAM,gBAAgB,OACpB,OACA,WACA,SAAiB,QACjB,OAAe,sBACf,aACA,eAA+B,EAAE,KAEjC,MAAMA,wBACJ,GAAG,iBAAiB,mBACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GACJ,OAAO,SAAS;GAChB;GACA;GACA;GACA,GAAI,eAAe,EAAE,aAAa;GACnC;EACF,CACF;AAEH,QAAO;EACL;EACA;EACA;EACA;EACA;EACD;;;;;;;;AASH,MAAa,iBAAiBC,6CAAe,aAAa"}
1
+ {"version":3,"file":"gitlab.cjs","names":["editor","fetcher","createEndpoint"],"sources":["../../../src/getIntlayerAPI/gitlab.ts"],"sourcesContent":["import { editor } from '@intlayer/config/built';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { createEndpoint } from '../cms/createIntlayerCMS';\nimport { type FetcherOptions, fetcher } from '../fetcher';\n\nexport type GitLabProject = {\n id: number;\n name: string;\n path_with_namespace: string;\n web_url: string;\n default_branch: string;\n visibility: string;\n last_activity_at: string;\n namespace: {\n id: number;\n name: string;\n path: string;\n };\n};\n\nexport type GitLabAuthCallbackBody = {\n code: string;\n redirectUri: string;\n instanceUrl?: string;\n};\n\nexport type GitLabAuthCallbackResult = {\n data: {\n token: string;\n };\n};\n\nexport type GitLabListProjectsResult = {\n data: GitLabProject[];\n};\n\nexport type GitLabCheckConfigBody = {\n token?: string;\n projectId: number;\n branch?: string;\n instanceUrl?: string;\n};\n\nexport type GitLabCheckConfigResult = {\n data: {\n hasConfig: boolean;\n configPaths: string[];\n };\n};\n\nexport type GitLabGetConfigFileBody = {\n token?: string;\n projectId: number;\n branch?: string;\n path?: string;\n instanceUrl?: string;\n};\n\nexport type GitLabGetConfigFileResult = {\n data: {\n content: string;\n };\n};\n\nexport type GitLabGetAuthUrlResult = {\n data: {\n authUrl: string;\n };\n};\n\nexport const getGitlabAPI = (\n authAPIOptions: FetcherOptions = {},\n intlayerConfig?: IntlayerConfig\n) => {\n const backendURL = intlayerConfig?.editor?.backendURL ?? editor.backendURL;\n\n const GITLAB_API_ROUTE = `${backendURL}/api/gitlab`;\n\n /**\n * Get GitLab OAuth authorization URL\n * @param redirectUri - Redirect URI after OAuth authorization\n * @param instanceUrl - Custom GitLab instance URL (optional, for self-hosted)\n */\n const getAuthUrl = async (\n redirectUri: string,\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabGetAuthUrlResult>(\n `${GITLAB_API_ROUTE}/auth-url`,\n authAPIOptions,\n otherOptions,\n {\n params: { redirectUri, ...(instanceUrl && { instanceUrl }) },\n }\n );\n\n /**\n * Exchange GitLab authorization code for access token\n * @param code - GitLab authorization code\n * @param redirectUri - Redirect URI used in the authorization request\n * @param instanceUrl - Custom GitLab instance URL (optional)\n */\n const authenticate = async (\n code: string,\n redirectUri: string,\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabAuthCallbackResult>(\n `${GITLAB_API_ROUTE}/auth`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: { code, redirectUri, instanceUrl },\n }\n );\n\n /**\n * Get user's GitLab projects\n * @param token - Optional GitLab access token. If not provided, backend will use session.\n * @param instanceUrl - Custom GitLab instance URL (optional)\n */\n const getProjects = async (\n token?: string | null,\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabListProjectsResult>(\n `${GITLAB_API_ROUTE}/projects`,\n authAPIOptions,\n otherOptions,\n {\n params: {\n ...(token && { token }),\n ...(instanceUrl && { instanceUrl }),\n },\n }\n );\n\n /**\n * Check if intlayer.config.ts exists in a GitLab repository\n * @param token - Optional GitLab access token. If not provided, backend will use session.\n * @param projectId - GitLab project ID\n * @param branch - Branch name (default: 'main')\n * @param instanceUrl - Custom GitLab instance URL (optional)\n */\n const checkIntlayerConfig = async (\n token: string | null | undefined,\n projectId: number,\n branch: string = 'main',\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabCheckConfigResult>(\n `${GITLAB_API_ROUTE}/check-config`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: {\n token: token ?? undefined,\n projectId,\n branch,\n ...(instanceUrl && { instanceUrl }),\n },\n }\n );\n\n /**\n * Get intlayer.config.ts file contents from a GitLab repository\n * @param token - Optional GitLab access token. If not provided, backend will use session.\n * @param projectId - GitLab project ID\n * @param branch - Branch name (default: 'main')\n * @param path - File path (default: 'intlayer.config.ts')\n * @param instanceUrl - Custom GitLab instance URL (optional)\n */\n const getConfigFile = async (\n token: string | null | undefined,\n projectId: number,\n branch: string = 'main',\n path: string = 'intlayer.config.ts',\n instanceUrl?: string,\n otherOptions: FetcherOptions = {}\n ) =>\n await fetcher<GitLabGetConfigFileResult>(\n `${GITLAB_API_ROUTE}/get-config-file`,\n authAPIOptions,\n otherOptions,\n {\n method: 'POST',\n body: {\n token: token ?? undefined,\n projectId,\n branch,\n path,\n ...(instanceUrl && { instanceUrl }),\n },\n }\n );\n\n return {\n getAuthUrl,\n authenticate,\n getProjects,\n checkIntlayerConfig,\n getConfigFile,\n };\n};\n\n/**\n * Authenticated `gitlab` endpoint bound to an Intlayer CMS authenticator.\n *\n * Pass an authenticator created with `createIntlayerCMS`, or omit it to use\n * the build-time configuration (`@intlayer/config/built`).\n */\nexport const gitlabEndpoint = createEndpoint(getGitlabAPI);\n"],"mappings":";;;;;;AAsEA,MAAa,gBACX,iBAAiC,CAAC,GAClC,mBACG;CAGH,MAAM,mBAAmB,GAFN,gBAAgB,QAAQ,cAAcA,8BAAO,WAEzB;;;;;;CAOvC,MAAM,aAAa,OACjB,aACA,aACA,eAA+B,CAAC,MAEhC,MAAMC,wBACJ,GAAG,iBAAiB,YACpB,gBACA,cACA,EACE,QAAQ;EAAE;EAAa,GAAI,eAAe,EAAE,YAAY;CAAG,EAC7D,CACF;;;;;;;CAQF,MAAM,eAAe,OACnB,MACA,aACA,aACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,iBAAiB,QACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GAAE;GAAM;GAAa;EAAY;CACzC,CACF;;;;;;CAOF,MAAM,cAAc,OAClB,OACA,aACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,iBAAiB,YACpB,gBACA,cACA,EACE,QAAQ;EACN,GAAI,SAAS,EAAE,MAAM;EACrB,GAAI,eAAe,EAAE,YAAY;CACnC,EACF,CACF;;;;;;;;CASF,MAAM,sBAAsB,OAC1B,OACA,WACA,SAAiB,QACjB,aACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,iBAAiB,gBACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GACJ,OAAO,SAAS;GAChB;GACA;GACA,GAAI,eAAe,EAAE,YAAY;EACnC;CACF,CACF;;;;;;;;;CAUF,MAAM,gBAAgB,OACpB,OACA,WACA,SAAiB,QACjB,OAAe,sBACf,aACA,eAA+B,CAAC,MAEhC,MAAMA,wBACJ,GAAG,iBAAiB,mBACpB,gBACA,cACA;EACE,QAAQ;EACR,MAAM;GACJ,OAAO,SAAS;GAChB;GACA;GACA;GACA,GAAI,eAAe,EAAE,YAAY;EACnC;CACF,CACF;CAEF,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF;;;;;;;AAQA,MAAa,iBAAiBC,6CAAe,YAAY"}