twenty-sdk 2.55.0 → 2.56.0
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.
- package/dist/billing/index.cjs.map +1 -1
- package/dist/billing/index.mjs.map +1 -1
- package/dist/define/index.cjs +11 -11
- package/dist/define/index.cjs.map +1 -1
- package/dist/define/index.d.ts +493 -339
- package/dist/define/index.mjs +3507 -3375
- package/dist/define/index.mjs.map +1 -1
- package/dist/front-component/index.cjs +1 -1
- package/dist/front-component/index.cjs.map +1 -1
- package/dist/front-component/index.d.ts +2 -0
- package/dist/front-component/index.mjs +3 -3
- package/dist/front-component/index.mjs.map +1 -1
- package/dist/logic-function/index.cjs +103 -23
- package/dist/logic-function/index.cjs.map +1 -1
- package/dist/logic-function/index.d.ts +179 -30
- package/dist/logic-function/index.mjs +363 -134
- package/dist/logic-function/index.mjs.map +1 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../../twenty-shared/dist/application-runtime.mjs","../../src/sdk/utils/get-application-access-token.ts","../../src/sdk/billing/charge-credits.ts","../../src/sdk/billing/get-credit-availability.ts"],"sourcesContent":["//#region src/application-runtime/constants/ConnectionScopeByLegacyVisibility.ts\nvar e = {\n\tuser: \"USER\",\n\tworkspace: \"WORKSPACE\"\n}, t = \"TWENTY_API_KEY\", n = \"TWENTY_API_URL\", r = \"TWENTY_APP_ACCESS_TOKEN\", i = \"TWENTY_APP_APPLICATION_ACCESS_TOKEN\", a = \"TWENTY_FUNCTIONS_URL\", o = \"TWENTY_SERVER_ROUTES_URL\", s = {\n\tUSER: \"user\",\n\tWORKSPACE: \"workspace\"\n}, c = [\n\t\"workspace-suspended\",\n\t\"no-subscription\",\n\t\"no-credits\"\n];\n//#endregion\nexport { e as CONNECTION_SCOPE_BY_LEGACY_VISIBILITY, c as CREDIT_UNAVAILABLE_REASONS, t as DEFAULT_API_KEY_NAME, n as DEFAULT_API_URL_NAME, r as DEFAULT_APP_ACCESS_TOKEN_NAME, i as DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME, a as DEFAULT_FUNCTIONS_URL_NAME, o as DEFAULT_SERVER_ROUTES_URL_NAME, s as LEGACY_CONNECTION_VISIBILITY_BY_SCOPE };\n","import {\n DEFAULT_APP_ACCESS_TOKEN_NAME,\n DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME,\n} from 'twenty-shared/application-runtime';\n\n// These reach the application's own resources, so prefer the application token when the runtime injects one\nexport const getApplicationAccessToken = (): string | undefined =>\n process.env[DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME] ??\n process.env[DEFAULT_APP_ACCESS_TOKEN_NAME];\n","import { type UsageOperationTypeValue } from 'twenty-shared/application';\nimport { DEFAULT_API_URL_NAME } from 'twenty-shared/application-runtime';\n\nimport { getApplicationAccessToken } from '@/sdk/utils/get-application-access-token';\n\nconst BILLING_CHARGE_TIMEOUT_MS = 5_000;\n\nexport type ChargeCreditsParams = {\n creditsUsedMicro: number;\n quantity?: number;\n // Who the spend belongs to when no user triggered the run (webhook, cron); ignored otherwise\n userWorkspaceId?: string;\n} & (\n | {\n // An operation declared in the manifest's `billing.operations`; the platform resolves its category and label\n operation: string;\n operationType?: never;\n resourceContext?: never;\n }\n | {\n // Platform billing category; omitted, the charge lands in the dedicated APP_OPERATION category\n operationType?: UsageOperationTypeValue;\n operation?: never;\n resourceContext?: string;\n }\n);\n\n// No-ops without an API URL or access token, and never throws: a billing error must not fail a tool\nexport const chargeCredits = async ({\n creditsUsedMicro,\n quantity = 1,\n operation,\n operationType,\n resourceContext,\n userWorkspaceId,\n}: ChargeCreditsParams): Promise<void> => {\n const apiUrl = process.env[DEFAULT_API_URL_NAME];\n const token = getApplicationAccessToken();\n\n if (!apiUrl || !token) {\n return;\n }\n\n try {\n const response = await fetch(\n `${apiUrl.replace(/\\/$/, '')}/app/billing/charge`,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n creditsUsedMicro,\n quantity,\n operation,\n operationType,\n resourceContext,\n userWorkspaceId,\n }),\n signal: AbortSignal.timeout(BILLING_CHARGE_TIMEOUT_MS),\n },\n );\n\n if (!response.ok) {\n const body = await response.text().catch(() => '');\n\n console.error(\n `chargeCredits: ${response.status} ${response.statusText}: ${body}`,\n );\n }\n } catch (error) {\n console.error(\n `chargeCredits: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n","import {\n CREDIT_UNAVAILABLE_REASONS,\n type CreditAvailability,\n type CreditUnavailableReason,\n DEFAULT_API_URL_NAME,\n} from 'twenty-shared/application-runtime';\n\nimport { getApplicationAccessToken } from '@/sdk/utils/get-application-access-token';\n\nconst CREDIT_AVAILABILITY_TIMEOUT_MS = 5_000;\n\n// A fresh object per call, since app code could mutate a shared constant\nconst available = (): CreditAvailability => ({ hasAvailableCredits: true });\n\nconst parseCreditAvailability = (body: unknown): CreditAvailability | null => {\n if (typeof body !== 'object' || body === null) {\n return null;\n }\n\n const { hasAvailableCredits, reason } = body as {\n hasAvailableCredits?: unknown;\n reason?: unknown;\n };\n\n if (hasAvailableCredits === true) {\n return { hasAvailableCredits: true };\n }\n\n if (\n hasAvailableCredits === false &&\n CREDIT_UNAVAILABLE_REASONS.includes(reason as CreditUnavailableReason)\n ) {\n return {\n hasAvailableCredits: false,\n reason: reason as CreditUnavailableReason,\n };\n }\n\n return null;\n};\n\n// Fails open on timeouts or bad responses: a hint before expensive work, never an authorization decision\nexport const getCreditAvailability = async (): Promise<CreditAvailability> => {\n const apiUrl = process.env[DEFAULT_API_URL_NAME];\n const token = getApplicationAccessToken();\n\n if (!apiUrl || !token) {\n return available();\n }\n\n try {\n const response = await fetch(\n `${apiUrl.replace(/\\/$/, '')}/app/billing/credits`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(CREDIT_AVAILABILITY_TIMEOUT_MS),\n },\n );\n\n if (!response.ok) {\n console.error(\n `getCreditAvailability: ${response.status} ${response.statusText}`,\n );\n\n return available();\n }\n\n const creditAvailability = parseCreditAvailability(await response.json());\n\n if (creditAvailability === null) {\n console.error('getCreditAvailability: unexpected response shape');\n\n return available();\n }\n\n return creditAvailability;\n } catch (error) {\n console.error(\n `getCreditAvailability: ${error instanceof Error ? error.message : String(error)}`,\n );\n\n return available();\n }\n};\n"],"mappings":"uEAIyB,EAAI,iBAG1B,EAAI,CACN,sBACA,kBACA,YACD,ECLa,MACX,QAAQ,IAAA,qCACR,QAAQ,IAAA,wBCHJ,EAA4B,IAuBrB,EAAgB,MAAO,CAClC,mBACA,WAAW,EACX,YACA,gBACA,kBACA,qBACwC,CACxC,IAAM,EAAS,QAAQ,IAAI,GACrB,EAAQ,EAA0B,EAEpC,MAAC,GAAU,CAAC,GAIhB,GAAI,CACF,IAAM,EAAW,MAAM,MACrB,GAAG,EAAO,QAAQ,MAAO,EAAE,EAAE,qBAC7B,CACE,OAAQ,OACR,QAAS,CACP,cAAe,UAAU,IACzB,eAAgB,kBAClB,EACA,KAAM,KAAK,UAAU,CACnB,mBACA,WACA,YACA,gBACA,kBACA,iBACF,CAAC,EACD,OAAQ,YAAY,QAAQ,CAAyB,CACvD,CACF,EAEA,GAAI,CAAC,EAAS,GAAI,CAChB,IAAM,EAAO,MAAM,EAAS,KAAK,CAAC,CAAC,UAAY,EAAE,EAEjD,QAAQ,MACN,kBAAkB,EAAS,OAAO,GAAG,EAAS,WAAW,IAAI,GAC/D,CACF,CACF,OAAS,EAAO,CACd,QAAQ,MACN,kBAAkB,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GACzE,CACF,CACF,ECnEM,EAAiC,IAGjC,OAAuC,CAAE,oBAAqB,EAAK,GAEnE,EAA2B,GAA6C,CAC5E,GAAI,OAAO,GAAS,WAAY,EAC9B,OAAO,KAGT,GAAM,CAAE,sBAAqB,UAAW,EAmBxC,OAdI,IAAwB,GACnB,CAAE,oBAAqB,EAAK,EAInC,IAAwB,IACxB,EAA2B,SAAS,CAAiC,EAE9D,CACL,oBAAqB,GACb,QACV,EAGK,IACT,EAGa,EAAwB,SAAyC,CAC5E,IAAM,EAAS,QAAQ,IAAI,GACrB,EAAQ,EAA0B,EAExC,GAAI,CAAC,GAAU,CAAC,EACd,OAAO,EAAU,EAGnB,GAAI,CACF,IAAM,EAAW,MAAM,MACrB,GAAG,EAAO,QAAQ,MAAO,EAAE,EAAE,sBAC7B,CACE,OAAQ,MACR,QAAS,CACP,cAAe,UAAU,IACzB,OAAQ,kBACV,EACA,OAAQ,YAAY,QAAQ,CAA8B,CAC5D,CACF,EAEA,GAAI,CAAC,EAAS,GAKZ,OAJA,QAAQ,MACN,0BAA0B,EAAS,OAAO,GAAG,EAAS,YACxD,EAEO,EAAU,EAGnB,IAAM,EAAqB,EAAwB,MAAM,EAAS,KAAK,CAAC,EAQxE,OANI,IAAuB,MACzB,QAAQ,MAAM,kDAAkD,EAEzD,EAAU,GAGZ,CACT,OAAS,EAAO,CAKd,OAJA,QAAQ,MACN,0BAA0B,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GACjF,EAEO,EAAU,CACnB,CACF"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../../twenty-shared/dist/application-runtime.mjs","../../src/sdk/utils/get-application-access-token.ts","../../src/sdk/billing/charge-credits.ts","../../src/sdk/billing/get-credit-availability.ts"],"sourcesContent":["//#region src/application-runtime/constants/ConnectionScopeByLegacyVisibility.ts\nvar e = {\n\tuser: \"USER\",\n\tworkspace: \"WORKSPACE\"\n}, t = \"TWENTY_API_KEY\", n = \"TWENTY_API_URL\", r = \"TWENTY_APP_ACCESS_TOKEN\", i = \"TWENTY_APP_APPLICATION_ACCESS_TOKEN\", a = \"TWENTY_FUNCTIONS_URL\", o = \"TWENTY_SERVER_ROUTES_URL\", s = {\n\tUSER: \"user\",\n\tWORKSPACE: \"workspace\"\n}, c = [\n\t\"workspace-suspended\",\n\t\"no-subscription\",\n\t\"no-credits\"\n];\n//#endregion\nexport { e as CONNECTION_SCOPE_BY_LEGACY_VISIBILITY, c as CREDIT_UNAVAILABLE_REASONS, t as DEFAULT_API_KEY_NAME, n as DEFAULT_API_URL_NAME, r as DEFAULT_APP_ACCESS_TOKEN_NAME, i as DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME, a as DEFAULT_FUNCTIONS_URL_NAME, o as DEFAULT_SERVER_ROUTES_URL_NAME, s as LEGACY_CONNECTION_VISIBILITY_BY_SCOPE };\n","import {\n DEFAULT_APP_ACCESS_TOKEN_NAME,\n DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME,\n} from 'twenty-shared/application-runtime';\n\n// These reach the application's own resources, so prefer the application token when the runtime injects one\nexport const getApplicationAccessToken = (): string | undefined =>\n process.env[DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME] ??\n process.env[DEFAULT_APP_ACCESS_TOKEN_NAME];\n\n// acts as whoever triggered the run, like the client SDK's default runAs\nexport const getCallerAccessToken = (): string | undefined =>\n process.env[DEFAULT_APP_ACCESS_TOKEN_NAME] ??\n process.env[DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME];\n","import { type UsageOperationTypeValue } from 'twenty-shared/application';\nimport { DEFAULT_API_URL_NAME } from 'twenty-shared/application-runtime';\n\nimport { getApplicationAccessToken } from '@/sdk/utils/get-application-access-token';\n\nconst BILLING_CHARGE_TIMEOUT_MS = 5_000;\n\nexport type ChargeCreditsParams = {\n creditsUsedMicro: number;\n quantity?: number;\n // Who the spend belongs to when no user triggered the run (webhook, cron); ignored otherwise\n userWorkspaceId?: string;\n} & (\n | {\n // An operation declared in the manifest's `billing.operations`; the platform resolves its category and label\n operation: string;\n operationType?: never;\n resourceContext?: never;\n }\n | {\n // Platform billing category; omitted, the charge lands in the dedicated APP_OPERATION category\n operationType?: UsageOperationTypeValue;\n operation?: never;\n resourceContext?: string;\n }\n);\n\n// No-ops without an API URL or access token, and never throws: a billing error must not fail a tool\nexport const chargeCredits = async ({\n creditsUsedMicro,\n quantity = 1,\n operation,\n operationType,\n resourceContext,\n userWorkspaceId,\n}: ChargeCreditsParams): Promise<void> => {\n const apiUrl = process.env[DEFAULT_API_URL_NAME];\n const token = getApplicationAccessToken();\n\n if (!apiUrl || !token) {\n return;\n }\n\n try {\n const response = await fetch(\n `${apiUrl.replace(/\\/$/, '')}/app/billing/charge`,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n creditsUsedMicro,\n quantity,\n operation,\n operationType,\n resourceContext,\n userWorkspaceId,\n }),\n signal: AbortSignal.timeout(BILLING_CHARGE_TIMEOUT_MS),\n },\n );\n\n if (!response.ok) {\n const body = await response.text().catch(() => '');\n\n console.error(\n `chargeCredits: ${response.status} ${response.statusText}: ${body}`,\n );\n }\n } catch (error) {\n console.error(\n `chargeCredits: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n","import {\n CREDIT_UNAVAILABLE_REASONS,\n type CreditAvailability,\n type CreditUnavailableReason,\n DEFAULT_API_URL_NAME,\n} from 'twenty-shared/application-runtime';\n\nimport { getApplicationAccessToken } from '@/sdk/utils/get-application-access-token';\n\nconst CREDIT_AVAILABILITY_TIMEOUT_MS = 5_000;\n\n// A fresh object per call, since app code could mutate a shared constant\nconst available = (): CreditAvailability => ({ hasAvailableCredits: true });\n\nconst parseCreditAvailability = (body: unknown): CreditAvailability | null => {\n if (typeof body !== 'object' || body === null) {\n return null;\n }\n\n const { hasAvailableCredits, reason } = body as {\n hasAvailableCredits?: unknown;\n reason?: unknown;\n };\n\n if (hasAvailableCredits === true) {\n return { hasAvailableCredits: true };\n }\n\n if (\n hasAvailableCredits === false &&\n CREDIT_UNAVAILABLE_REASONS.includes(reason as CreditUnavailableReason)\n ) {\n return {\n hasAvailableCredits: false,\n reason: reason as CreditUnavailableReason,\n };\n }\n\n return null;\n};\n\n// Fails open on timeouts or bad responses: a hint before expensive work, never an authorization decision\nexport const getCreditAvailability = async (): Promise<CreditAvailability> => {\n const apiUrl = process.env[DEFAULT_API_URL_NAME];\n const token = getApplicationAccessToken();\n\n if (!apiUrl || !token) {\n return available();\n }\n\n try {\n const response = await fetch(\n `${apiUrl.replace(/\\/$/, '')}/app/billing/credits`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(CREDIT_AVAILABILITY_TIMEOUT_MS),\n },\n );\n\n if (!response.ok) {\n console.error(\n `getCreditAvailability: ${response.status} ${response.statusText}`,\n );\n\n return available();\n }\n\n const creditAvailability = parseCreditAvailability(await response.json());\n\n if (creditAvailability === null) {\n console.error('getCreditAvailability: unexpected response shape');\n\n return available();\n }\n\n return creditAvailability;\n } catch (error) {\n console.error(\n `getCreditAvailability: ${error instanceof Error ? error.message : String(error)}`,\n );\n\n return available();\n }\n};\n"],"mappings":"uEAIyB,EAAI,iBAG1B,EAAI,CACN,sBACA,kBACA,YACD,ECLa,MACX,QAAQ,IAAA,qCACR,QAAQ,IAAA,wBCHJ,EAA4B,IAuBrB,EAAgB,MAAO,CAClC,mBACA,WAAW,EACX,YACA,gBACA,kBACA,qBACwC,CACxC,IAAM,EAAS,QAAQ,IAAI,GACrB,EAAQ,EAA0B,EAEpC,MAAC,GAAU,CAAC,GAIhB,GAAI,CACF,IAAM,EAAW,MAAM,MACrB,GAAG,EAAO,QAAQ,MAAO,EAAE,EAAE,qBAC7B,CACE,OAAQ,OACR,QAAS,CACP,cAAe,UAAU,IACzB,eAAgB,kBAClB,EACA,KAAM,KAAK,UAAU,CACnB,mBACA,WACA,YACA,gBACA,kBACA,iBACF,CAAC,EACD,OAAQ,YAAY,QAAQ,CAAyB,CACvD,CACF,EAEA,GAAI,CAAC,EAAS,GAAI,CAChB,IAAM,EAAO,MAAM,EAAS,KAAK,CAAC,CAAC,UAAY,EAAE,EAEjD,QAAQ,MACN,kBAAkB,EAAS,OAAO,GAAG,EAAS,WAAW,IAAI,GAC/D,CACF,CACF,OAAS,EAAO,CACd,QAAQ,MACN,kBAAkB,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GACzE,CACF,CACF,ECnEM,EAAiC,IAGjC,OAAuC,CAAE,oBAAqB,EAAK,GAEnE,EAA2B,GAA6C,CAC5E,GAAI,OAAO,GAAS,WAAY,EAC9B,OAAO,KAGT,GAAM,CAAE,sBAAqB,UAAW,EAmBxC,OAdI,IAAwB,GACnB,CAAE,oBAAqB,EAAK,EAInC,IAAwB,IACxB,EAA2B,SAAS,CAAiC,EAE9D,CACL,oBAAqB,GACb,QACV,EAGK,IACT,EAGa,EAAwB,SAAyC,CAC5E,IAAM,EAAS,QAAQ,IAAI,GACrB,EAAQ,EAA0B,EAExC,GAAI,CAAC,GAAU,CAAC,EACd,OAAO,EAAU,EAGnB,GAAI,CACF,IAAM,EAAW,MAAM,MACrB,GAAG,EAAO,QAAQ,MAAO,EAAE,EAAE,sBAC7B,CACE,OAAQ,MACR,QAAS,CACP,cAAe,UAAU,IACzB,OAAQ,kBACV,EACA,OAAQ,YAAY,QAAQ,CAA8B,CAC5D,CACF,EAEA,GAAI,CAAC,EAAS,GAKZ,OAJA,QAAQ,MACN,0BAA0B,EAAS,OAAO,GAAG,EAAS,YACxD,EAEO,EAAU,EAGnB,IAAM,EAAqB,EAAwB,MAAM,EAAS,KAAK,CAAC,EAQxE,OANI,IAAuB,MACzB,QAAQ,MAAM,kDAAkD,EAEzD,EAAU,GAGZ,CACT,OAAS,EAAO,CAKd,OAJA,QAAQ,MACN,0BAA0B,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GACjF,EAEO,EAAU,CACnB,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../twenty-shared/dist/application-runtime.mjs","../../src/sdk/utils/get-application-access-token.ts","../../src/sdk/billing/charge-credits.ts","../../src/sdk/billing/get-credit-availability.ts"],"sourcesContent":["//#region src/application-runtime/constants/ConnectionScopeByLegacyVisibility.ts\nvar e = {\n\tuser: \"USER\",\n\tworkspace: \"WORKSPACE\"\n}, t = \"TWENTY_API_KEY\", n = \"TWENTY_API_URL\", r = \"TWENTY_APP_ACCESS_TOKEN\", i = \"TWENTY_APP_APPLICATION_ACCESS_TOKEN\", a = \"TWENTY_FUNCTIONS_URL\", o = \"TWENTY_SERVER_ROUTES_URL\", s = {\n\tUSER: \"user\",\n\tWORKSPACE: \"workspace\"\n}, c = [\n\t\"workspace-suspended\",\n\t\"no-subscription\",\n\t\"no-credits\"\n];\n//#endregion\nexport { e as CONNECTION_SCOPE_BY_LEGACY_VISIBILITY, c as CREDIT_UNAVAILABLE_REASONS, t as DEFAULT_API_KEY_NAME, n as DEFAULT_API_URL_NAME, r as DEFAULT_APP_ACCESS_TOKEN_NAME, i as DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME, a as DEFAULT_FUNCTIONS_URL_NAME, o as DEFAULT_SERVER_ROUTES_URL_NAME, s as LEGACY_CONNECTION_VISIBILITY_BY_SCOPE };\n","import {\n DEFAULT_APP_ACCESS_TOKEN_NAME,\n DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME,\n} from 'twenty-shared/application-runtime';\n\n// These reach the application's own resources, so prefer the application token when the runtime injects one\nexport const getApplicationAccessToken = (): string | undefined =>\n process.env[DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME] ??\n process.env[DEFAULT_APP_ACCESS_TOKEN_NAME];\n","import { type UsageOperationTypeValue } from 'twenty-shared/application';\nimport { DEFAULT_API_URL_NAME } from 'twenty-shared/application-runtime';\n\nimport { getApplicationAccessToken } from '@/sdk/utils/get-application-access-token';\n\nconst BILLING_CHARGE_TIMEOUT_MS = 5_000;\n\nexport type ChargeCreditsParams = {\n creditsUsedMicro: number;\n quantity?: number;\n // Who the spend belongs to when no user triggered the run (webhook, cron); ignored otherwise\n userWorkspaceId?: string;\n} & (\n | {\n // An operation declared in the manifest's `billing.operations`; the platform resolves its category and label\n operation: string;\n operationType?: never;\n resourceContext?: never;\n }\n | {\n // Platform billing category; omitted, the charge lands in the dedicated APP_OPERATION category\n operationType?: UsageOperationTypeValue;\n operation?: never;\n resourceContext?: string;\n }\n);\n\n// No-ops without an API URL or access token, and never throws: a billing error must not fail a tool\nexport const chargeCredits = async ({\n creditsUsedMicro,\n quantity = 1,\n operation,\n operationType,\n resourceContext,\n userWorkspaceId,\n}: ChargeCreditsParams): Promise<void> => {\n const apiUrl = process.env[DEFAULT_API_URL_NAME];\n const token = getApplicationAccessToken();\n\n if (!apiUrl || !token) {\n return;\n }\n\n try {\n const response = await fetch(\n `${apiUrl.replace(/\\/$/, '')}/app/billing/charge`,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n creditsUsedMicro,\n quantity,\n operation,\n operationType,\n resourceContext,\n userWorkspaceId,\n }),\n signal: AbortSignal.timeout(BILLING_CHARGE_TIMEOUT_MS),\n },\n );\n\n if (!response.ok) {\n const body = await response.text().catch(() => '');\n\n console.error(\n `chargeCredits: ${response.status} ${response.statusText}: ${body}`,\n );\n }\n } catch (error) {\n console.error(\n `chargeCredits: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n","import {\n CREDIT_UNAVAILABLE_REASONS,\n type CreditAvailability,\n type CreditUnavailableReason,\n DEFAULT_API_URL_NAME,\n} from 'twenty-shared/application-runtime';\n\nimport { getApplicationAccessToken } from '@/sdk/utils/get-application-access-token';\n\nconst CREDIT_AVAILABILITY_TIMEOUT_MS = 5_000;\n\n// A fresh object per call, since app code could mutate a shared constant\nconst available = (): CreditAvailability => ({ hasAvailableCredits: true });\n\nconst parseCreditAvailability = (body: unknown): CreditAvailability | null => {\n if (typeof body !== 'object' || body === null) {\n return null;\n }\n\n const { hasAvailableCredits, reason } = body as {\n hasAvailableCredits?: unknown;\n reason?: unknown;\n };\n\n if (hasAvailableCredits === true) {\n return { hasAvailableCredits: true };\n }\n\n if (\n hasAvailableCredits === false &&\n CREDIT_UNAVAILABLE_REASONS.includes(reason as CreditUnavailableReason)\n ) {\n return {\n hasAvailableCredits: false,\n reason: reason as CreditUnavailableReason,\n };\n }\n\n return null;\n};\n\n// Fails open on timeouts or bad responses: a hint before expensive work, never an authorization decision\nexport const getCreditAvailability = async (): Promise<CreditAvailability> => {\n const apiUrl = process.env[DEFAULT_API_URL_NAME];\n const token = getApplicationAccessToken();\n\n if (!apiUrl || !token) {\n return available();\n }\n\n try {\n const response = await fetch(\n `${apiUrl.replace(/\\/$/, '')}/app/billing/credits`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(CREDIT_AVAILABILITY_TIMEOUT_MS),\n },\n );\n\n if (!response.ok) {\n console.error(\n `getCreditAvailability: ${response.status} ${response.statusText}`,\n );\n\n return available();\n }\n\n const creditAvailability = parseCreditAvailability(await response.json());\n\n if (creditAvailability === null) {\n console.error('getCreditAvailability: unexpected response shape');\n\n return available();\n }\n\n return creditAvailability;\n } catch (error) {\n console.error(\n `getCreditAvailability: ${error instanceof Error ? error.message : String(error)}`,\n );\n\n return available();\n }\n};\n"],"mappings":";IAIyB,IAAI,kBAG1B,IAAI;CACN;CACA;CACA;AACD,GCLa,UACX,QAAQ,IAAA,uCACR,QAAQ,IAAA,yBCHJ,IAA4B,KAuBrB,IAAgB,OAAO,EAClC,qBACA,cAAW,GACX,cACA,kBACA,oBACA,yBACwC;CACxC,IAAM,IAAS,QAAQ,IAAI,IACrB,IAAQ,EAA0B;CAEpC,OAAC,KAAU,CAAC,IAIhB,IAAI;EACF,IAAM,IAAW,MAAM,MACrB,GAAG,EAAO,QAAQ,OAAO,EAAE,EAAE,sBAC7B;GACE,QAAQ;GACR,SAAS;IACP,eAAe,UAAU;IACzB,gBAAgB;GAClB;GACA,MAAM,KAAK,UAAU;IACnB;IACA;IACA;IACA;IACA;IACA;GACF,CAAC;GACD,QAAQ,YAAY,QAAQ,CAAyB;EACvD,CACF;EAEA,IAAI,CAAC,EAAS,IAAI;GAChB,IAAM,IAAO,MAAM,EAAS,KAAK,CAAC,CAAC,YAAY,EAAE;GAEjD,QAAQ,MACN,kBAAkB,EAAS,OAAO,GAAG,EAAS,WAAW,IAAI,GAC/D;EACF;CACF,SAAS,GAAO;EACd,QAAQ,MACN,kBAAkB,aAAiB,QAAQ,EAAM,UAAU,OAAO,CAAK,GACzE;CACF;AACF,GCnEM,IAAiC,KAGjC,WAAuC,EAAE,qBAAqB,GAAK,IAEnE,KAA2B,MAA6C;CAC5E,IAAI,OAAO,KAAS,aAAY,GAC9B,OAAO;CAGT,IAAM,EAAE,wBAAqB,cAAW;CAmBxC,OAdI,MAAwB,KACnB,EAAE,qBAAqB,GAAK,IAInC,MAAwB,MACxB,EAA2B,SAAS,CAAiC,IAE9D;EACL,qBAAqB;EACb;CACV,IAGK;AACT,GAGa,IAAwB,YAAyC;CAC5E,IAAM,IAAS,QAAQ,IAAI,IACrB,IAAQ,EAA0B;CAExC,IAAI,CAAC,KAAU,CAAC,GACd,OAAO,EAAU;CAGnB,IAAI;EACF,IAAM,IAAW,MAAM,MACrB,GAAG,EAAO,QAAQ,OAAO,EAAE,EAAE,uBAC7B;GACE,QAAQ;GACR,SAAS;IACP,eAAe,UAAU;IACzB,QAAQ;GACV;GACA,QAAQ,YAAY,QAAQ,CAA8B;EAC5D,CACF;EAEA,IAAI,CAAC,EAAS,IAKZ,OAJA,QAAQ,MACN,0BAA0B,EAAS,OAAO,GAAG,EAAS,YACxD,GAEO,EAAU;EAGnB,IAAM,IAAqB,EAAwB,MAAM,EAAS,KAAK,CAAC;EAQxE,OANI,MAAuB,QACzB,QAAQ,MAAM,kDAAkD,GAEzD,EAAU,KAGZ;CACT,SAAS,GAAO;EAKd,OAJA,QAAQ,MACN,0BAA0B,aAAiB,QAAQ,EAAM,UAAU,OAAO,CAAK,GACjF,GAEO,EAAU;CACnB;AACF"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../twenty-shared/dist/application-runtime.mjs","../../src/sdk/utils/get-application-access-token.ts","../../src/sdk/billing/charge-credits.ts","../../src/sdk/billing/get-credit-availability.ts"],"sourcesContent":["//#region src/application-runtime/constants/ConnectionScopeByLegacyVisibility.ts\nvar e = {\n\tuser: \"USER\",\n\tworkspace: \"WORKSPACE\"\n}, t = \"TWENTY_API_KEY\", n = \"TWENTY_API_URL\", r = \"TWENTY_APP_ACCESS_TOKEN\", i = \"TWENTY_APP_APPLICATION_ACCESS_TOKEN\", a = \"TWENTY_FUNCTIONS_URL\", o = \"TWENTY_SERVER_ROUTES_URL\", s = {\n\tUSER: \"user\",\n\tWORKSPACE: \"workspace\"\n}, c = [\n\t\"workspace-suspended\",\n\t\"no-subscription\",\n\t\"no-credits\"\n];\n//#endregion\nexport { e as CONNECTION_SCOPE_BY_LEGACY_VISIBILITY, c as CREDIT_UNAVAILABLE_REASONS, t as DEFAULT_API_KEY_NAME, n as DEFAULT_API_URL_NAME, r as DEFAULT_APP_ACCESS_TOKEN_NAME, i as DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME, a as DEFAULT_FUNCTIONS_URL_NAME, o as DEFAULT_SERVER_ROUTES_URL_NAME, s as LEGACY_CONNECTION_VISIBILITY_BY_SCOPE };\n","import {\n DEFAULT_APP_ACCESS_TOKEN_NAME,\n DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME,\n} from 'twenty-shared/application-runtime';\n\n// These reach the application's own resources, so prefer the application token when the runtime injects one\nexport const getApplicationAccessToken = (): string | undefined =>\n process.env[DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME] ??\n process.env[DEFAULT_APP_ACCESS_TOKEN_NAME];\n\n// acts as whoever triggered the run, like the client SDK's default runAs\nexport const getCallerAccessToken = (): string | undefined =>\n process.env[DEFAULT_APP_ACCESS_TOKEN_NAME] ??\n process.env[DEFAULT_APP_APPLICATION_ACCESS_TOKEN_NAME];\n","import { type UsageOperationTypeValue } from 'twenty-shared/application';\nimport { DEFAULT_API_URL_NAME } from 'twenty-shared/application-runtime';\n\nimport { getApplicationAccessToken } from '@/sdk/utils/get-application-access-token';\n\nconst BILLING_CHARGE_TIMEOUT_MS = 5_000;\n\nexport type ChargeCreditsParams = {\n creditsUsedMicro: number;\n quantity?: number;\n // Who the spend belongs to when no user triggered the run (webhook, cron); ignored otherwise\n userWorkspaceId?: string;\n} & (\n | {\n // An operation declared in the manifest's `billing.operations`; the platform resolves its category and label\n operation: string;\n operationType?: never;\n resourceContext?: never;\n }\n | {\n // Platform billing category; omitted, the charge lands in the dedicated APP_OPERATION category\n operationType?: UsageOperationTypeValue;\n operation?: never;\n resourceContext?: string;\n }\n);\n\n// No-ops without an API URL or access token, and never throws: a billing error must not fail a tool\nexport const chargeCredits = async ({\n creditsUsedMicro,\n quantity = 1,\n operation,\n operationType,\n resourceContext,\n userWorkspaceId,\n}: ChargeCreditsParams): Promise<void> => {\n const apiUrl = process.env[DEFAULT_API_URL_NAME];\n const token = getApplicationAccessToken();\n\n if (!apiUrl || !token) {\n return;\n }\n\n try {\n const response = await fetch(\n `${apiUrl.replace(/\\/$/, '')}/app/billing/charge`,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n creditsUsedMicro,\n quantity,\n operation,\n operationType,\n resourceContext,\n userWorkspaceId,\n }),\n signal: AbortSignal.timeout(BILLING_CHARGE_TIMEOUT_MS),\n },\n );\n\n if (!response.ok) {\n const body = await response.text().catch(() => '');\n\n console.error(\n `chargeCredits: ${response.status} ${response.statusText}: ${body}`,\n );\n }\n } catch (error) {\n console.error(\n `chargeCredits: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n","import {\n CREDIT_UNAVAILABLE_REASONS,\n type CreditAvailability,\n type CreditUnavailableReason,\n DEFAULT_API_URL_NAME,\n} from 'twenty-shared/application-runtime';\n\nimport { getApplicationAccessToken } from '@/sdk/utils/get-application-access-token';\n\nconst CREDIT_AVAILABILITY_TIMEOUT_MS = 5_000;\n\n// A fresh object per call, since app code could mutate a shared constant\nconst available = (): CreditAvailability => ({ hasAvailableCredits: true });\n\nconst parseCreditAvailability = (body: unknown): CreditAvailability | null => {\n if (typeof body !== 'object' || body === null) {\n return null;\n }\n\n const { hasAvailableCredits, reason } = body as {\n hasAvailableCredits?: unknown;\n reason?: unknown;\n };\n\n if (hasAvailableCredits === true) {\n return { hasAvailableCredits: true };\n }\n\n if (\n hasAvailableCredits === false &&\n CREDIT_UNAVAILABLE_REASONS.includes(reason as CreditUnavailableReason)\n ) {\n return {\n hasAvailableCredits: false,\n reason: reason as CreditUnavailableReason,\n };\n }\n\n return null;\n};\n\n// Fails open on timeouts or bad responses: a hint before expensive work, never an authorization decision\nexport const getCreditAvailability = async (): Promise<CreditAvailability> => {\n const apiUrl = process.env[DEFAULT_API_URL_NAME];\n const token = getApplicationAccessToken();\n\n if (!apiUrl || !token) {\n return available();\n }\n\n try {\n const response = await fetch(\n `${apiUrl.replace(/\\/$/, '')}/app/billing/credits`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(CREDIT_AVAILABILITY_TIMEOUT_MS),\n },\n );\n\n if (!response.ok) {\n console.error(\n `getCreditAvailability: ${response.status} ${response.statusText}`,\n );\n\n return available();\n }\n\n const creditAvailability = parseCreditAvailability(await response.json());\n\n if (creditAvailability === null) {\n console.error('getCreditAvailability: unexpected response shape');\n\n return available();\n }\n\n return creditAvailability;\n } catch (error) {\n console.error(\n `getCreditAvailability: ${error instanceof Error ? error.message : String(error)}`,\n );\n\n return available();\n }\n};\n"],"mappings":";IAIyB,IAAI,kBAG1B,IAAI;CACN;CACA;CACA;AACD,GCLa,UACX,QAAQ,IAAA,uCACR,QAAQ,IAAA,yBCHJ,IAA4B,KAuBrB,IAAgB,OAAO,EAClC,qBACA,cAAW,GACX,cACA,kBACA,oBACA,yBACwC;CACxC,IAAM,IAAS,QAAQ,IAAI,IACrB,IAAQ,EAA0B;CAEpC,OAAC,KAAU,CAAC,IAIhB,IAAI;EACF,IAAM,IAAW,MAAM,MACrB,GAAG,EAAO,QAAQ,OAAO,EAAE,EAAE,sBAC7B;GACE,QAAQ;GACR,SAAS;IACP,eAAe,UAAU;IACzB,gBAAgB;GAClB;GACA,MAAM,KAAK,UAAU;IACnB;IACA;IACA;IACA;IACA;IACA;GACF,CAAC;GACD,QAAQ,YAAY,QAAQ,CAAyB;EACvD,CACF;EAEA,IAAI,CAAC,EAAS,IAAI;GAChB,IAAM,IAAO,MAAM,EAAS,KAAK,CAAC,CAAC,YAAY,EAAE;GAEjD,QAAQ,MACN,kBAAkB,EAAS,OAAO,GAAG,EAAS,WAAW,IAAI,GAC/D;EACF;CACF,SAAS,GAAO;EACd,QAAQ,MACN,kBAAkB,aAAiB,QAAQ,EAAM,UAAU,OAAO,CAAK,GACzE;CACF;AACF,GCnEM,IAAiC,KAGjC,WAAuC,EAAE,qBAAqB,GAAK,IAEnE,KAA2B,MAA6C;CAC5E,IAAI,OAAO,KAAS,aAAY,GAC9B,OAAO;CAGT,IAAM,EAAE,wBAAqB,cAAW;CAmBxC,OAdI,MAAwB,KACnB,EAAE,qBAAqB,GAAK,IAInC,MAAwB,MACxB,EAA2B,SAAS,CAAiC,IAE9D;EACL,qBAAqB;EACb;CACV,IAGK;AACT,GAGa,IAAwB,YAAyC;CAC5E,IAAM,IAAS,QAAQ,IAAI,IACrB,IAAQ,EAA0B;CAExC,IAAI,CAAC,KAAU,CAAC,GACd,OAAO,EAAU;CAGnB,IAAI;EACF,IAAM,IAAW,MAAM,MACrB,GAAG,EAAO,QAAQ,OAAO,EAAE,EAAE,uBAC7B;GACE,QAAQ;GACR,SAAS;IACP,eAAe,UAAU;IACzB,QAAQ;GACV;GACA,QAAQ,YAAY,QAAQ,CAA8B;EAC5D,CACF;EAEA,IAAI,CAAC,EAAS,IAKZ,OAJA,QAAQ,MACN,0BAA0B,EAAS,OAAO,GAAG,EAAS,YACxD,GAEO,EAAU;EAGnB,IAAM,IAAqB,EAAwB,MAAM,EAAS,KAAK,CAAC;EAQxE,OANI,MAAuB,QACzB,QAAQ,MAAM,kDAAkD,GAEzD,EAAU,KAGZ;CACT,SAAS,GAAO;EAKd,OAJA,QAAQ,MACN,0BAA0B,aAAiB,QAAQ,EAAM,UAAU,OAAO,CAAK,GACjF,GAEO,EAAU;CACnB;AACF"}
|