{"version":3,"sources":["../lib/urls.ts","../lib/request.ts","../lib/configure.ts","../lib/oauth.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import {\n  FigmaOAuthUrlParam,\n  FigmaOAuthTokenRequestParam,\n  FigmaOAuthTokenRefreshParam,\n} from \"./types\";\n\n/**\n * example:\n *\n * `https://www.figma.com/api/oauth/token?`\n * - `client_id=:client_id&`\n * - `client_secret=:client_secret&`\n * - `redirect_uri=:callback&`\n * - `code=:code&`\n * - `grant_type=authorization_code`\n *\n * will return : https://accounts.grida.co/callback/figma-app-oauth?code=K3p9uhqlntNDrbLe2HMPAFgwf&state=\n */\nexport function oauthBrowserUrl({\n  client_id,\n  redirect_uri,\n  state,\n  scope = \"file_read\",\n  response_type = \"code\",\n}: FigmaOAuthUrlParam) {\n  const params = {\n    client_id: client_id,\n    redirect_uri: redirect_uri,\n    scope: scope,\n    state: state,\n    response_type: response_type,\n  };\n\n  const _q_str = new URLSearchParams(params).toString();\n  return `https://www.figma.com/oauth?${_q_str}`;\n}\n\n/**\n *\n */\nexport function oauthTokenRequestUrl({\n  client_id,\n  client_secret,\n  grant_type = \"authorization_code\",\n  redirect_uri,\n  code,\n}: FigmaOAuthTokenRequestParam) {\n  const params = {\n    client_id: client_id,\n    client_secret: client_secret,\n    grant_type: grant_type,\n    redirect_uri: redirect_uri,\n    code: code,\n  };\n  const _q_str = new URLSearchParams(params).toString();\n  return `https://www.figma.com/api/oauth/token?${_q_str}`;\n}\n\nexport function oauthTokenRefreshUrl({\n  client_id,\n  client_secret,\n  refresh_token,\n}: FigmaOAuthTokenRefreshParam): string {\n  const params = {\n    client_id: client_id,\n    client_secret: client_secret,\n    refresh_token: refresh_token,\n  };\n  const _q_str = new URLSearchParams(params).toString();\n  return `https://www.figma.com/api/oauth/refresh?${_q_str}`;\n}\n\nexport const urls = {\n  oauth_token_request_url: oauthTokenRequestUrl,\n  oauth_token_refresh_url: oauthTokenRefreshUrl,\n  oauth_browser_url: oauthBrowserUrl,\n};\n","import Axios from \"axios\";\nimport {\n  FigmaOAuthTokenRequestParam,\n  FigmaOAuthTokenResponse,\n  FigmaOAuthTokenRefreshResponse,\n  FigmaOAuthTokenRefreshParam,\n} from \"./types\";\nimport { oauthTokenRefreshUrl, oauthTokenRequestUrl } from \"./urls\";\n\n/**\n * The format of the response body is:\n * ```json\n *  {\n      \"access_token\": \"<TOKEN>\",\n      \"expires_in\": \"<EXPIRATION (in seconds)>\",\n      \"refresh_token\": \"<REFRESH TOKEN>\"\n    }\n * ``` \n */\nexport async function requestOauthToken({\n  client_id,\n  client_secret,\n  grant_type = \"authorization_code\",\n  redirect_uri,\n  code,\n}: FigmaOAuthTokenRequestParam): Promise<FigmaOAuthTokenResponse> {\n  const res = await Axios.post<FigmaOAuthTokenResponse>(\n    oauthTokenRequestUrl({\n      client_id,\n      client_secret,\n      redirect_uri,\n      grant_type,\n      code,\n    })\n  );\n\n  return res.data;\n}\n\n/**\n * [Refreshing OAuth tokens](https://www.figma.com/developers/api#refresh-oauth2)\n * \n * ```\n    POST https://www.figma.com/api/oauth/refresh?\n    client_id=:client_id&\n    client_secret=:client_secret&\n    refresh_token=:refresh_token\n\n    {\n        \"access_token\": <TOKEN>,\n        \"expires_in\": <EXPIRATION (in seconds)>,\n    }\n * ```\n */\nexport async function refreshOauthToken({\n  client_id,\n  client_secret,\n  refresh_token,\n}: FigmaOAuthTokenRefreshParam): Promise<FigmaOAuthTokenRefreshResponse> {\n  const res = await Axios.post<FigmaOAuthTokenRefreshResponse>(\n    oauthTokenRefreshUrl({\n      client_id,\n      client_secret,\n      refresh_token,\n    })\n  );\n\n  return res.data;\n}\n\nexport const request = {\n  authentication: requestOauthToken,\n  tokenrefresh: refreshOauthToken,\n};\n","/**\n * configure figma app in a global scope.\n * if you've already loaded env variables, without explicitely calling this method,\n * still the package will work with referenced variable **`FIGMA_APP_CLIENT_ID`** and **`FIGMA_APP_CLIENT_SECRET`**\n */\nexport function configure({\n  client_id,\n  client_secret,\n  redirect_uri,\n}: {\n  client_id?: string;\n  client_secret?: string;\n  redirect_uri?: string;\n}) {\n  __client_id = client_id;\n  __client_secret = client_secret;\n  __redirect_uri = redirect_uri;\n}\n\nlet __client_id: string = process.env.FIGMA_APP_CLIENT_ID;\nlet __client_secret: string = process.env.FIGMA_APP_CLIENT_SECRET;\nlet __redirect_uri: string = process.env.FIGMA_OAUTH_CALLBACL_URI;\nexport function __cfg_get_client_id(): string {\n  return __client_id;\n}\nexport function __cfg_get_client_secret(): string {\n  return __client_secret;\n}\nexport function __cfg_get_redirect_uri(): string {\n  return __redirect_uri;\n}\n","import { OAuthStage } from \"./types\";\nimport { request } from \"./request\";\nimport { urls } from \"./urls\";\nimport {\n  __cfg_get_client_id,\n  __cfg_get_client_secret,\n  __cfg_get_redirect_uri,\n} from \"./configure\";\n\nexport class OAuth {\n  static readonly _authprocs = new Map<string, OAuthState>();\n  static new({\n    state,\n    redirect_uri,\n  }: {\n    state?: string;\n    redirect_uri?: string;\n  }): OAuthState {\n    const oauth = new OAuthState({ state, redirect_uri });\n    this._authprocs.set(oauth.state, oauth);\n    return oauth;\n  }\n\n  static get(state: string): OAuthState {\n    return this._authprocs.get(state);\n  }\n\n  static resolve(state: string) {\n    this._authprocs.delete(state);\n  }\n}\n\nexport class OAuthState {\n  private _stage: OAuthStage;\n  readonly _app_id: string;\n  readonly _app_secret: string;\n  readonly redirect_uri: string;\n  get stage(): OAuthStage {\n    return this._stage;\n  }\n  readonly state: string;\n\n  constructor({\n    state = _stateid(),\n    redirect_uri = __cfg_get_redirect_uri(),\n  }: {\n    state?: string;\n    redirect_uri?: string;\n  }) {\n    this.state = state;\n\n    this._app_id = __cfg_get_client_id();\n    this._app_secret = __cfg_get_client_secret();\n    if (!redirect_uri) {\n      throw \"redirect_uri must be provided by configuration. use `.env` or `configure()`.\";\n    }\n    this.redirect_uri = redirect_uri;\n  }\n\n  get authUrl(): string {\n    return urls.oauth_browser_url({\n      client_id: this._app_id,\n      redirect_uri: this.redirect_uri,\n      state: this.state,\n    });\n  }\n\n  async authenticate({ code }: { code: string }) {\n    return await request.authentication({\n      client_id: this._app_id,\n      client_secret: this._app_secret,\n      grant_type: \"authorization_code\",\n      redirect_uri: this.redirect_uri,\n      code: code,\n    });\n  }\n\n  resolve() {\n    try {\n      OAuth.resolve(this.state);\n    } catch (_) {\n      throw new Error(\n        \"Unable to resolve OAuth state: This OAuthState was not initialized by `OAuth.new()`\"\n      );\n    }\n  }\n}\n\nfunction _stateid(): string {\n  // random string gen - ref: https://stackoverflow.com/a/8084248/5463235\n  return Math.random().toString(36).substring(7);\n}\n"]}