@stackframe/stack-shared 2.8.47 → 2.8.49
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/CHANGELOG.md +12 -0
- package/dist/apps/apps-config.d.mts +8 -8
- package/dist/apps/apps-config.d.ts +8 -8
- package/dist/apps/apps-config.js +8 -8
- package/dist/apps/apps-config.js.map +1 -1
- package/dist/config/schema-fuzzer.test.js +0 -9
- package/dist/config/schema-fuzzer.test.js.map +1 -1
- package/dist/config/schema.d.mts +193 -307
- package/dist/config/schema.d.ts +193 -307
- package/dist/config/schema.js +11 -19
- package/dist/config/schema.js.map +1 -1
- package/dist/esm/apps/apps-config.js +8 -8
- package/dist/esm/apps/apps-config.js.map +1 -1
- package/dist/esm/config/schema-fuzzer.test.js +0 -9
- package/dist/esm/config/schema-fuzzer.test.js.map +1 -1
- package/dist/esm/config/schema.js +11 -19
- package/dist/esm/config/schema.js.map +1 -1
- package/dist/esm/interface/admin-interface.js +10 -0
- package/dist/esm/interface/admin-interface.js.map +1 -1
- package/dist/esm/interface/client-interface.js +11 -7
- package/dist/esm/interface/client-interface.js.map +1 -1
- package/dist/esm/interface/crud/projects.js +2 -1
- package/dist/esm/interface/crud/projects.js.map +1 -1
- package/dist/esm/known-errors.js +1 -21
- package/dist/esm/known-errors.js.map +1 -1
- package/dist/esm/schema-fields.js +17 -1
- package/dist/esm/schema-fields.js.map +1 -1
- package/dist/esm/utils/caches.js +17 -9
- package/dist/esm/utils/caches.js.map +1 -1
- package/dist/esm/utils/ips.js.map +1 -1
- package/dist/esm/utils/urls.js.map +1 -1
- package/dist/interface/admin-interface.d.mts +6 -0
- package/dist/interface/admin-interface.d.ts +6 -0
- package/dist/interface/admin-interface.js +10 -0
- package/dist/interface/admin-interface.js.map +1 -1
- package/dist/interface/client-interface.d.mts +3 -2
- package/dist/interface/client-interface.d.ts +3 -2
- package/dist/interface/client-interface.js +11 -7
- package/dist/interface/client-interface.js.map +1 -1
- package/dist/interface/crud/products.d.mts +9 -0
- package/dist/interface/crud/products.d.ts +9 -0
- package/dist/interface/crud/projects.d.mts +10 -0
- package/dist/interface/crud/projects.d.ts +10 -0
- package/dist/interface/crud/projects.js +2 -1
- package/dist/interface/crud/projects.js.map +1 -1
- package/dist/known-errors.d.mts +0 -6
- package/dist/known-errors.d.ts +0 -6
- package/dist/known-errors.js +1 -21
- package/dist/known-errors.js.map +1 -1
- package/dist/schema-fields.d.mts +53 -1
- package/dist/schema-fields.d.ts +53 -1
- package/dist/schema-fields.js +21 -1
- package/dist/schema-fields.js.map +1 -1
- package/dist/utils/caches.d.mts +7 -7
- package/dist/utils/caches.d.ts +7 -7
- package/dist/utils/caches.js +17 -9
- package/dist/utils/caches.js.map +1 -1
- package/dist/utils/ips.d.mts +1 -1
- package/dist/utils/ips.d.ts +1 -1
- package/dist/utils/ips.js.map +1 -1
- package/dist/utils/urls.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/urls.tsx"],"sourcesContent":["import { generateSecureRandomString } from \"./crypto\";\nimport { templateIdentity } from \"./strings\";\n\nexport function createUrlIfValid(...args: ConstructorParameters<typeof URL>) {\n try {\n return new URL(...args);\n } catch (e) {\n return null;\n }\n}\nundefined?.test(\"createUrlIfValid\", ({ expect }) => {\n // Test with valid URLs\n expect(createUrlIfValid(\"https://example.com\")).toBeInstanceOf(URL);\n expect(createUrlIfValid(\"https://example.com/path?query=value#hash\")).toBeInstanceOf(URL);\n expect(createUrlIfValid(\"/path\", \"https://example.com\")).toBeInstanceOf(URL);\n\n // Test with invalid URLs\n expect(createUrlIfValid(\"\")).toBeNull();\n expect(createUrlIfValid(\"not a url\")).toBeNull();\n expect(createUrlIfValid(\"http://\")).toBeNull();\n});\n\nexport function isValidUrl(url: string) {\n return !!createUrlIfValid(url);\n}\nundefined?.test(\"isValidUrl\", ({ expect }) => {\n // Test with valid URLs\n expect(isValidUrl(\"https://example.com\")).toBe(true);\n expect(isValidUrl(\"http://localhost:3000\")).toBe(true);\n expect(isValidUrl(\"ftp://example.com\")).toBe(true);\n\n // Test with invalid URLs\n expect(isValidUrl(\"\")).toBe(false);\n expect(isValidUrl(\"not a url\")).toBe(false);\n expect(isValidUrl(\"http://\")).toBe(false);\n});\n\nexport function isValidHostname(hostname: string) {\n // Basic validation\n if (!hostname || hostname.startsWith('.') || hostname.endsWith('.') || hostname.includes('..')) {\n return false;\n }\n\n const url = createUrlIfValid(`https://${hostname}`);\n if (!url) return false;\n return url.hostname === hostname;\n}\nundefined?.test(\"isValidHostname\", ({ expect }) => {\n // Test with valid hostnames\n expect(isValidHostname(\"example.com\")).toBe(true);\n expect(isValidHostname(\"localhost\")).toBe(true);\n expect(isValidHostname(\"sub.domain.example.com\")).toBe(true);\n expect(isValidHostname(\"127.0.0.1\")).toBe(true);\n\n // Test with invalid hostnames\n expect(isValidHostname(\"\")).toBe(false);\n expect(isValidHostname(\"example.com/path\")).toBe(false);\n expect(isValidHostname(\"https://example.com\")).toBe(false);\n expect(isValidHostname(\"example com\")).toBe(false);\n});\n\nexport function isValidHostnameWithWildcards(hostname: string) {\n // Empty hostnames are invalid\n if (!hostname) return false;\n\n // Check if it contains wildcards\n const hasWildcard = hostname.includes('*');\n\n if (!hasWildcard) {\n // If no wildcards, validate as a normal hostname\n return isValidHostname(hostname);\n }\n\n // Basic validation checks that apply even with wildcards\n // - Hostname cannot start or end with a dot\n if (hostname.startsWith('.') || hostname.endsWith('.')) {\n return false;\n }\n\n // - No consecutive dots\n if (hostname.includes('..')) {\n return false;\n }\n\n // For wildcard validation, check that non-wildcard parts contain valid characters\n // Replace wildcards with a valid placeholder to check the rest\n const testHostname = hostname.replace(/\\*+/g, 'wildcard');\n\n // Check if the resulting string would be a valid hostname\n if (!/^[a-zA-Z0-9.-]+$/.test(testHostname)) {\n return false;\n }\n\n // Additional check: ensure the pattern makes sense\n // Check each segment between wildcards\n const segments = hostname.split(/\\*+/);\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (segment === '') continue; // Empty segments are OK (consecutive wildcards)\n\n // First segment can't start with dot\n if (i === 0 && segment.startsWith('.')) {\n return false;\n }\n\n // Last segment can't end with dot\n if (i === segments.length - 1 && segment.endsWith('.')) {\n return false;\n }\n\n // No segment should have consecutive dots\n if (segment.includes('..')) {\n return false;\n }\n }\n\n return true;\n}\nundefined?.test(\"isValidHostnameWithWildcards\", ({ expect }) => {\n // Test with valid regular hostnames\n expect(isValidHostnameWithWildcards(\"example.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"localhost\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"sub.domain.example.com\")).toBe(true);\n\n // Test with valid wildcard hostnames\n expect(isValidHostnameWithWildcards(\"*.example.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"a-*.example.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"*.*.org\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"**.example.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"sub.**.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"*-api.*.com\")).toBe(true);\n\n // Test with invalid hostnames\n expect(isValidHostnameWithWildcards(\"\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"example.com/path\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"https://example.com\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"example com\")).toBe(false);\n expect(isValidHostnameWithWildcards(\".example.com\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"example.com.\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"example..com\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"*.example..com\")).toBe(false);\n});\n\nexport function matchHostnamePattern(pattern: string, hostname: string): boolean {\n // If no wildcards, it's an exact match\n if (!pattern.includes('*')) {\n return pattern === hostname;\n }\n\n // Convert the pattern to a regex\n // First, escape all regex special characters except *\n let regexPattern = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n // Use a placeholder for ** to handle it separately from single *\n const doubleWildcardPlaceholder = '\\x00DOUBLE_WILDCARD\\x00';\n regexPattern = regexPattern.replace(/\\*\\*/g, doubleWildcardPlaceholder);\n\n // Replace single * with a pattern that matches anything except dots\n regexPattern = regexPattern.replace(/\\*/g, '[^.]*');\n\n // Replace the double wildcard placeholder with a pattern that matches anything including dots\n regexPattern = regexPattern.replace(new RegExp(doubleWildcardPlaceholder, 'g'), '.*');\n\n // Anchor the pattern to match the entire hostname\n regexPattern = '^' + regexPattern + '$';\n\n try {\n const regex = new RegExp(regexPattern);\n return regex.test(hostname);\n } catch {\n return false;\n }\n}\nundefined?.test(\"matchHostnamePattern\", ({ expect }) => {\n // Test exact matches\n expect(matchHostnamePattern(\"example.com\", \"example.com\")).toBe(true);\n expect(matchHostnamePattern(\"example.com\", \"other.com\")).toBe(false);\n\n // Test single wildcard matches\n expect(matchHostnamePattern(\"*.example.com\", \"api.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"*.example.com\", \"www.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"*.example.com\", \"example.com\")).toBe(false);\n expect(matchHostnamePattern(\"*.example.com\", \"api.v2.example.com\")).toBe(false);\n\n // Test double wildcard matches\n expect(matchHostnamePattern(\"**.example.com\", \"api.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"**.example.com\", \"api.v2.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"**.example.com\", \"a.b.c.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"**.example.com\", \"example.com\")).toBe(false);\n\n // Test complex patterns\n expect(matchHostnamePattern(\"api-*.example.com\", \"api-v1.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"api-*.example.com\", \"api-v2.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"api-*.example.com\", \"api.example.com\")).toBe(false);\n expect(matchHostnamePattern(\"*.*.org\", \"mail.example.org\")).toBe(true);\n expect(matchHostnamePattern(\"*.*.org\", \"example.org\")).toBe(false);\n});\n\nexport function isLocalhost(urlOrString: string | URL) {\n const url = createUrlIfValid(urlOrString);\n if (!url) return false;\n if (url.hostname === \"localhost\" || url.hostname.endsWith(\".localhost\")) return true;\n if (url.hostname.match(/^127\\.\\d+\\.\\d+\\.\\d+$/)) return true;\n return false;\n}\nundefined?.test(\"isLocalhost\", ({ expect }) => {\n // Test with localhost URLs\n expect(isLocalhost(\"http://localhost\")).toBe(true);\n expect(isLocalhost(\"https://localhost:8080\")).toBe(true);\n expect(isLocalhost(\"http://sub.localhost\")).toBe(true);\n expect(isLocalhost(\"http://127.0.0.1\")).toBe(true);\n expect(isLocalhost(\"http://127.1.2.3\")).toBe(true);\n\n // Test with non-localhost URLs\n expect(isLocalhost(\"https://example.com\")).toBe(false);\n expect(isLocalhost(\"http://192.168.1.1\")).toBe(false);\n expect(isLocalhost(\"http://10.0.0.1\")).toBe(false);\n\n // Test with URL objects\n expect(isLocalhost(new URL(\"http://localhost\"))).toBe(true);\n expect(isLocalhost(new URL(\"https://example.com\"))).toBe(false);\n\n // Test with invalid URLs\n expect(isLocalhost(\"not a url\")).toBe(false);\n expect(isLocalhost(\"\")).toBe(false);\n});\n\nexport function isRelative(url: string) {\n const randomDomain = `${generateSecureRandomString()}.stack-auth.example.com`;\n const u = createUrlIfValid(url, `https://${randomDomain}`);\n if (!u) return false;\n if (u.host !== randomDomain) return false;\n if (u.protocol !== \"https:\") return false;\n return true;\n}\nundefined?.test(\"isRelative\", ({ expect }) => {\n // We can't easily mock generateSecureRandomString in this context\n // but we can still test the function's behavior\n\n // Test with relative URLs\n expect(isRelative(\"/\")).toBe(true);\n expect(isRelative(\"/path\")).toBe(true);\n expect(isRelative(\"/path?query=value#hash\")).toBe(true);\n\n // Test with absolute URLs\n expect(isRelative(\"https://example.com\")).toBe(false);\n expect(isRelative(\"http://example.com\")).toBe(false);\n expect(isRelative(\"//example.com\")).toBe(false);\n\n // Note: The implementation treats empty strings and invalid URLs as relative\n // This is because they can be resolved against a base URL\n expect(isRelative(\"\")).toBe(true);\n expect(isRelative(\"not a url\")).toBe(true);\n});\n\nexport function getRelativePart(url: URL) {\n return url.pathname + url.search + url.hash;\n}\nundefined?.test(\"getRelativePart\", ({ expect }) => {\n // Test with various URLs\n expect(getRelativePart(new URL(\"https://example.com\"))).toBe(\"/\");\n expect(getRelativePart(new URL(\"https://example.com/path\"))).toBe(\"/path\");\n expect(getRelativePart(new URL(\"https://example.com/path?query=value\"))).toBe(\"/path?query=value\");\n expect(getRelativePart(new URL(\"https://example.com/path#hash\"))).toBe(\"/path#hash\");\n expect(getRelativePart(new URL(\"https://example.com/path?query=value#hash\"))).toBe(\"/path?query=value#hash\");\n\n // Test with different domains but same paths\n const url1 = new URL(\"https://example.com/path?query=value#hash\");\n const url2 = new URL(\"https://different.com/path?query=value#hash\");\n expect(getRelativePart(url1)).toBe(getRelativePart(url2));\n});\n\n/**\n * A template literal tag that returns a URL.\n *\n * Any values passed are encoded.\n */\nexport function url(strings: TemplateStringsArray | readonly string[], ...values: (string|number|boolean)[]): URL {\n return new URL(urlString(strings, ...values));\n}\nundefined?.test(\"url\", ({ expect }) => {\n // Test with no interpolation\n expect(url`https://example.com`).toBeInstanceOf(URL);\n expect(url`https://example.com`.href).toBe(\"https://example.com/\");\n\n // Test with string interpolation\n expect(url`https://example.com/${\"path\"}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${\"path\"}`.pathname).toBe(\"/path\");\n\n // Test with number interpolation\n expect(url`https://example.com/${42}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${42}`.pathname).toBe(\"/42\");\n\n // Test with boolean interpolation\n expect(url`https://example.com/${true}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${true}`.pathname).toBe(\"/true\");\n\n // Test with special characters in interpolation\n expect(url`https://example.com/${\"path with spaces\"}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${\"path with spaces\"}`.pathname).toBe(\"/path%20with%20spaces\");\n\n // Test with multiple interpolations\n expect(url`https://example.com/${\"path\"}?query=${\"value\"}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${\"path\"}?query=${\"value\"}`.pathname).toBe(\"/path\");\n expect(url`https://example.com/${\"path\"}?query=${\"value\"}`.search).toBe(\"?query=value\");\n});\n\n\n/**\n * A template literal tag that returns a URL string.\n *\n * Any values passed are encoded.\n */\nexport function urlString(strings: TemplateStringsArray | readonly string[], ...values: (string|number|boolean)[]): string {\n return templateIdentity(strings, ...values.map(encodeURIComponent));\n}\nundefined?.test(\"urlString\", ({ expect }) => {\n // Test with no interpolation\n expect(urlString`https://example.com`).toBe(\"https://example.com\");\n\n // Test with string interpolation\n expect(urlString`https://example.com/${\"path\"}`).toBe(\"https://example.com/path\");\n\n // Test with number interpolation\n expect(urlString`https://example.com/${42}`).toBe(\"https://example.com/42\");\n\n // Test with boolean interpolation\n expect(urlString`https://example.com/${true}`).toBe(\"https://example.com/true\");\n\n // Test with special characters in interpolation\n expect(urlString`https://example.com/${\"path with spaces\"}`).toBe(\"https://example.com/path%20with%20spaces\");\n expect(urlString`https://example.com/${\"?&=\"}`).toBe(\"https://example.com/%3F%26%3D\");\n\n // Test with multiple interpolations\n expect(urlString`https://example.com/${\"path\"}?query=${\"value\"}`).toBe(\"https://example.com/path?query=value\");\n expect(urlString`https://example.com/${\"path\"}?query=${\"value with spaces\"}`).toBe(\"https://example.com/path?query=value%20with%20spaces\");\n});\n\nexport function isChildUrl(parentUrl: URL, maybeChildUrl: URL) {\n return parentUrl.origin === maybeChildUrl.origin\n && isChildPath(parentUrl.pathname, maybeChildUrl.pathname)\n && [...parentUrl.searchParams].every(([key, value]) => maybeChildUrl.searchParams.get(key) === value)\n && (!parentUrl.hash || parentUrl.hash === maybeChildUrl.hash);\n}\nundefined?.test(\"isChildUrl\", ({ expect }) => {\n // true\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://abc.com/\"))).toBe(true);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://abc.com/path\"))).toBe(true);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://abc.com/path?query=value\"))).toBe(true);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://abc.com/path?query=value#hash\"))).toBe(true);\n\n // false\n expect(isChildUrl(new URL(\"https://abc.com\"), new URL(\"https://example.com\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://example.com/path\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://example.com/path?query=value\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://example.com/path?query=value#hash\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://example.com\"), new URL(\"https://abc.com/path?query=value#hash\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://example.com?query=value123\"), new URL(\"https://example.com/path?query=value#hash\"))).toBe(false);\n});\n\nexport function isChildPath(parentPath: string, maybeChildPath: string) {\n parentPath = parentPath.endsWith(\"/\") ? parentPath : parentPath + \"/\";\n maybeChildPath = maybeChildPath.endsWith(\"/\") ? maybeChildPath : maybeChildPath + \"/\";\n return maybeChildPath.startsWith(parentPath);\n}\nundefined?.test(\"isSubPath\", ({ expect }) => {\n expect(isChildPath(\"/\", \"/\")).toBe(true);\n expect(isChildPath(\"/\", \"/path\")).toBe(true);\n expect(isChildPath(\"/path\", \"/\")).toBe(false);\n expect(isChildPath(\"/path\", \"/path\")).toBe(true);\n expect(isChildPath(\"/path/\", \"/path\")).toBe(true);\n expect(isChildPath(\"/path\", \"/path/\")).toBe(true);\n expect(isChildPath(\"/path/\", \"/path/\")).toBe(true);\n expect(isChildPath(\"/path\", \"/path/abc\")).toBe(true);\n expect(isChildPath(\"/path/\", \"/path/abc\")).toBe(true);\n expect(isChildPath(\"/path\", \"/path-abc\")).toBe(false);\n expect(isChildPath(\"/path\", \"/path-abc/\")).toBe(false);\n expect(isChildPath(\"/path/\", \"/path-abc\")).toBe(false);\n expect(isChildPath(\"/path/\", \"/path-abc/\")).toBe(false);\n});\n\n"],"mappings":";AAAA,SAAS,kCAAkC;AAC3C,SAAS,wBAAwB;AAE1B,SAAS,oBAAoB,MAAyC;AAC3E,MAAI;AACF,WAAO,IAAI,IAAI,GAAG,IAAI;AAAA,EACxB,SAAS,GAAG;AACV,WAAO;AAAA,EACT;AACF;AAaO,SAAS,WAAWA,MAAa;AACtC,SAAO,CAAC,CAAC,iBAAiBA,IAAG;AAC/B;AAaO,SAAS,gBAAgB,UAAkB;AAEhD,MAAI,CAAC,YAAY,SAAS,WAAW,GAAG,KAAK,SAAS,SAAS,GAAG,KAAK,SAAS,SAAS,IAAI,GAAG;AAC9F,WAAO;AAAA,EACT;AAEA,QAAMA,OAAM,iBAAiB,WAAW,QAAQ,EAAE;AAClD,MAAI,CAACA,KAAK,QAAO;AACjB,SAAOA,KAAI,aAAa;AAC1B;AAeO,SAAS,6BAA6B,UAAkB;AAE7D,MAAI,CAAC,SAAU,QAAO;AAGtB,QAAM,cAAc,SAAS,SAAS,GAAG;AAEzC,MAAI,CAAC,aAAa;AAEhB,WAAO,gBAAgB,QAAQ;AAAA,EACjC;AAIA,MAAI,SAAS,WAAW,GAAG,KAAK,SAAS,SAAS,GAAG,GAAG;AACtD,WAAO;AAAA,EACT;AAGA,MAAI,SAAS,SAAS,IAAI,GAAG;AAC3B,WAAO;AAAA,EACT;AAIA,QAAM,eAAe,SAAS,QAAQ,QAAQ,UAAU;AAGxD,MAAI,CAAC,mBAAmB,KAAK,YAAY,GAAG;AAC1C,WAAO;AAAA,EACT;AAIA,QAAM,WAAW,SAAS,MAAM,KAAK;AACrC,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,UAAU,SAAS,CAAC;AAC1B,QAAI,YAAY,GAAI;AAGpB,QAAI,MAAM,KAAK,QAAQ,WAAW,GAAG,GAAG;AACtC,aAAO;AAAA,IACT;AAGA,QAAI,MAAM,SAAS,SAAS,KAAK,QAAQ,SAAS,GAAG,GAAG;AACtD,aAAO;AAAA,IACT;AAGA,QAAI,QAAQ,SAAS,IAAI,GAAG;AAC1B,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AA0BO,SAAS,qBAAqB,SAAiB,UAA2B;AAE/E,MAAI,CAAC,QAAQ,SAAS,GAAG,GAAG;AAC1B,WAAO,YAAY;AAAA,EACrB;AAIA,MAAI,eAAe,QAAQ,QAAQ,sBAAsB,MAAM;AAG/D,QAAM,4BAA4B;AAClC,iBAAe,aAAa,QAAQ,SAAS,yBAAyB;AAGtE,iBAAe,aAAa,QAAQ,OAAO,OAAO;AAGlD,iBAAe,aAAa,QAAQ,IAAI,OAAO,2BAA2B,GAAG,GAAG,IAAI;AAGpF,iBAAe,MAAM,eAAe;AAEpC,MAAI;AACF,UAAM,QAAQ,IAAI,OAAO,YAAY;AACrC,WAAO,MAAM,KAAK,QAAQ;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA0BO,SAAS,YAAY,aAA2B;AACrD,QAAMA,OAAM,iBAAiB,WAAW;AACxC,MAAI,CAACA,KAAK,QAAO;AACjB,MAAIA,KAAI,aAAa,eAAeA,KAAI,SAAS,SAAS,YAAY,EAAG,QAAO;AAChF,MAAIA,KAAI,SAAS,MAAM,sBAAsB,EAAG,QAAO;AACvD,SAAO;AACT;AAuBO,SAAS,WAAWA,MAAa;AACtC,QAAM,eAAe,GAAG,2BAA2B,CAAC;AACpD,QAAM,IAAI,iBAAiBA,MAAK,WAAW,YAAY,EAAE;AACzD,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,EAAE,SAAS,aAAc,QAAO;AACpC,MAAI,EAAE,aAAa,SAAU,QAAO;AACpC,SAAO;AACT;AAqBO,SAAS,gBAAgBA,MAAU;AACxC,SAAOA,KAAI,WAAWA,KAAI,SAASA,KAAI;AACzC;AAoBO,SAAS,IAAI,YAAsD,QAAwC;AAChH,SAAO,IAAI,IAAI,UAAU,SAAS,GAAG,MAAM,CAAC;AAC9C;AAkCO,SAAS,UAAU,YAAsD,QAA2C;AACzH,SAAO,iBAAiB,SAAS,GAAG,OAAO,IAAI,kBAAkB,CAAC;AACpE;AAuBO,SAAS,WAAW,WAAgB,eAAoB;AAC7D,SAAO,UAAU,WAAW,cAAc,UACrC,YAAY,UAAU,UAAU,cAAc,QAAQ,KACtD,CAAC,GAAG,UAAU,YAAY,EAAE,MAAM,CAAC,CAAC,KAAK,KAAK,MAAM,cAAc,aAAa,IAAI,GAAG,MAAM,KAAK,MAChG,CAAC,UAAU,QAAQ,UAAU,SAAS,cAAc;AAC5D;AAiBO,SAAS,YAAY,YAAoB,gBAAwB;AACtE,eAAa,WAAW,SAAS,GAAG,IAAI,aAAa,aAAa;AAClE,mBAAiB,eAAe,SAAS,GAAG,IAAI,iBAAiB,iBAAiB;AAClF,SAAO,eAAe,WAAW,UAAU;AAC7C;","names":["url"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/urls.tsx"],"sourcesContent":["import { generateSecureRandomString } from \"./crypto\";\nimport { templateIdentity } from \"./strings\";\n\nexport function createUrlIfValid(...args: ConstructorParameters<typeof URL>) {\n try {\n return new URL(...args);\n } catch (e) {\n return null;\n }\n}\nundefined?.test(\"createUrlIfValid\", ({ expect }) => {\n // Test with valid URLs\n expect(createUrlIfValid(\"https://example.com\")).toBeInstanceOf(URL);\n expect(createUrlIfValid(\"https://example.com/path?query=value#hash\")).toBeInstanceOf(URL);\n expect(createUrlIfValid(\"/path\", \"https://example.com\")).toBeInstanceOf(URL);\n\n // Test with invalid URLs\n expect(createUrlIfValid(\"\")).toBeNull();\n expect(createUrlIfValid(\"not a url\")).toBeNull();\n expect(createUrlIfValid(\"http://\")).toBeNull();\n});\n\nexport function isValidUrl(url: string) {\n return !!createUrlIfValid(url);\n}\nundefined?.test(\"isValidUrl\", ({ expect }) => {\n // Test with valid URLs\n expect(isValidUrl(\"https://example.com\")).toBe(true);\n expect(isValidUrl(\"http://localhost:3000\")).toBe(true);\n expect(isValidUrl(\"ftp://example.com\")).toBe(true);\n\n // Test with invalid URLs\n expect(isValidUrl(\"\")).toBe(false);\n expect(isValidUrl(\"not a url\")).toBe(false);\n expect(isValidUrl(\"http://\")).toBe(false);\n});\n\nexport function isValidHostname(hostname: string) {\n // Basic validation\n if (!hostname || hostname.startsWith('.') || hostname.endsWith('.') || hostname.includes('..')) {\n return false;\n }\n\n const url = createUrlIfValid(`https://${hostname}`);\n if (!url) return false;\n return url.hostname === hostname;\n}\nundefined?.test(\"isValidHostname\", ({ expect }) => {\n // Test with valid hostnames\n expect(isValidHostname(\"example.com\")).toBe(true);\n expect(isValidHostname(\"localhost\")).toBe(true);\n expect(isValidHostname(\"sub.domain.example.com\")).toBe(true);\n expect(isValidHostname(\"127.0.0.1\")).toBe(true);\n\n // Test with invalid hostnames\n expect(isValidHostname(\"\")).toBe(false);\n expect(isValidHostname(\"example.com/path\")).toBe(false);\n expect(isValidHostname(\"https://example.com\")).toBe(false);\n expect(isValidHostname(\"example com\")).toBe(false);\n});\n\nexport function isValidHostnameWithWildcards(hostname: string) {\n // Empty hostnames are invalid\n if (!hostname) return false;\n\n // Check if it contains wildcards\n const hasWildcard = hostname.includes('*');\n\n if (!hasWildcard) {\n // If no wildcards, validate as a normal hostname\n return isValidHostname(hostname);\n }\n\n // Basic validation checks that apply even with wildcards\n // - Hostname cannot start or end with a dot\n if (hostname.startsWith('.') || hostname.endsWith('.')) {\n return false;\n }\n\n // - No consecutive dots\n if (hostname.includes('..')) {\n return false;\n }\n\n // For wildcard validation, check that non-wildcard parts contain valid characters\n // Replace wildcards with a valid placeholder to check the rest\n const testHostname = hostname.replace(/\\*+/g, 'wildcard');\n\n // Check if the resulting string would be a valid hostname\n if (!/^[a-zA-Z0-9.-]+$/.test(testHostname)) {\n return false;\n }\n\n // Additional check: ensure the pattern makes sense\n // Check each segment between wildcards\n const segments = hostname.split(/\\*+/);\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (segment === '') continue; // Empty segments are OK (consecutive wildcards)\n\n // First segment can't start with dot\n if (i === 0 && segment.startsWith('.')) {\n return false;\n }\n\n // Last segment can't end with dot\n if (i === segments.length - 1 && segment.endsWith('.')) {\n return false;\n }\n\n // No segment should have consecutive dots\n if (segment.includes('..')) {\n return false;\n }\n }\n\n return true;\n}\nundefined?.test(\"isValidHostnameWithWildcards\", ({ expect }) => {\n // Test with valid regular hostnames\n expect(isValidHostnameWithWildcards(\"example.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"localhost\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"sub.domain.example.com\")).toBe(true);\n\n // Test with valid wildcard hostnames\n expect(isValidHostnameWithWildcards(\"*.example.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"a-*.example.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"*.*.org\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"**.example.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"sub.**.com\")).toBe(true);\n expect(isValidHostnameWithWildcards(\"*-api.*.com\")).toBe(true);\n\n // Test with invalid hostnames\n expect(isValidHostnameWithWildcards(\"\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"example.com/path\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"https://example.com\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"example com\")).toBe(false);\n expect(isValidHostnameWithWildcards(\".example.com\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"example.com.\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"example..com\")).toBe(false);\n expect(isValidHostnameWithWildcards(\"*.example..com\")).toBe(false);\n});\n\nexport function matchHostnamePattern(pattern: string, hostname: string): boolean {\n // If no wildcards, it's an exact match\n if (!pattern.includes('*')) {\n return pattern === hostname;\n }\n\n // Convert the pattern to a regex\n // First, escape all regex special characters except *\n let regexPattern = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n // Use a placeholder for ** to handle it separately from single *\n const doubleWildcardPlaceholder = '\\x00DOUBLE_WILDCARD\\x00';\n regexPattern = regexPattern.replace(/\\*\\*/g, doubleWildcardPlaceholder);\n\n // Replace single * with a pattern that matches anything except dots\n regexPattern = regexPattern.replace(/\\*/g, '[^.]*');\n\n // Replace the double wildcard placeholder with a pattern that matches anything including dots\n regexPattern = regexPattern.replace(new RegExp(doubleWildcardPlaceholder, 'g'), '.*');\n\n // Anchor the pattern to match the entire hostname\n regexPattern = '^' + regexPattern + '$';\n\n try {\n const regex = new RegExp(regexPattern);\n return regex.test(hostname);\n } catch {\n return false;\n }\n}\nundefined?.test(\"matchHostnamePattern\", ({ expect }) => {\n // Test exact matches\n expect(matchHostnamePattern(\"example.com\", \"example.com\")).toBe(true);\n expect(matchHostnamePattern(\"example.com\", \"other.com\")).toBe(false);\n\n // Test single wildcard matches\n expect(matchHostnamePattern(\"*.example.com\", \"api.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"*.example.com\", \"www.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"*.example.com\", \"example.com\")).toBe(false);\n expect(matchHostnamePattern(\"*.example.com\", \"api.v2.example.com\")).toBe(false);\n\n // Test double wildcard matches\n expect(matchHostnamePattern(\"**.example.com\", \"api.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"**.example.com\", \"api.v2.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"**.example.com\", \"a.b.c.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"**.example.com\", \"example.com\")).toBe(false);\n\n // Test complex patterns\n expect(matchHostnamePattern(\"api-*.example.com\", \"api-v1.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"api-*.example.com\", \"api-v2.example.com\")).toBe(true);\n expect(matchHostnamePattern(\"api-*.example.com\", \"api.example.com\")).toBe(false);\n expect(matchHostnamePattern(\"*.*.org\", \"mail.example.org\")).toBe(true);\n expect(matchHostnamePattern(\"*.*.org\", \"example.org\")).toBe(false);\n});\n\nexport function isLocalhost(urlOrString: string | URL) {\n const url = createUrlIfValid(urlOrString);\n if (!url) return false;\n if (url.hostname === \"localhost\" || url.hostname.endsWith(\".localhost\")) return true;\n if (url.hostname.match(/^127\\.\\d+\\.\\d+\\.\\d+$/)) return true;\n return false;\n}\nundefined?.test(\"isLocalhost\", ({ expect }) => {\n // Test with localhost URLs\n expect(isLocalhost(\"http://localhost\")).toBe(true);\n expect(isLocalhost(\"https://localhost:8080\")).toBe(true);\n expect(isLocalhost(\"http://sub.localhost\")).toBe(true);\n expect(isLocalhost(\"http://127.0.0.1\")).toBe(true);\n expect(isLocalhost(\"http://127.1.2.3\")).toBe(true);\n\n // Test with non-localhost URLs\n expect(isLocalhost(\"https://example.com\")).toBe(false);\n expect(isLocalhost(\"http://192.168.1.1\")).toBe(false);\n expect(isLocalhost(\"http://10.0.0.1\")).toBe(false);\n\n // Test with URL objects\n expect(isLocalhost(new URL(\"http://localhost\"))).toBe(true);\n expect(isLocalhost(new URL(\"https://example.com\"))).toBe(false);\n\n // Test with invalid URLs\n expect(isLocalhost(\"not a url\")).toBe(false);\n expect(isLocalhost(\"\")).toBe(false);\n});\n\nexport function isRelative(url: string) {\n const randomDomain = `${generateSecureRandomString()}.stack-auth.example.com`;\n const u = createUrlIfValid(url, `https://${randomDomain}`);\n if (!u) return false;\n if (u.host !== randomDomain) return false;\n if (u.protocol !== \"https:\") return false;\n return true;\n}\nundefined?.test(\"isRelative\", ({ expect }) => {\n // We can't easily mock generateSecureRandomString in this context\n // but we can still test the function's behavior\n\n // Test with relative URLs\n expect(isRelative(\"/\")).toBe(true);\n expect(isRelative(\"/path\")).toBe(true);\n expect(isRelative(\"/path?query=value#hash\")).toBe(true);\n\n // Test with absolute URLs\n expect(isRelative(\"https://example.com\")).toBe(false);\n expect(isRelative(\"http://example.com\")).toBe(false);\n expect(isRelative(\"//example.com\")).toBe(false);\n\n // Note: The implementation treats empty strings and invalid URLs as relative\n // This is because they can be resolved against a base URL\n expect(isRelative(\"\")).toBe(true);\n expect(isRelative(\"not a url\")).toBe(true);\n});\n\nexport function getRelativePart(url: URL) {\n return url.pathname + url.search + url.hash;\n}\nundefined?.test(\"getRelativePart\", ({ expect }) => {\n // Test with various URLs\n expect(getRelativePart(new URL(\"https://example.com\"))).toBe(\"/\");\n expect(getRelativePart(new URL(\"https://example.com/path\"))).toBe(\"/path\");\n expect(getRelativePart(new URL(\"https://example.com/path?query=value\"))).toBe(\"/path?query=value\");\n expect(getRelativePart(new URL(\"https://example.com/path#hash\"))).toBe(\"/path#hash\");\n expect(getRelativePart(new URL(\"https://example.com/path?query=value#hash\"))).toBe(\"/path?query=value#hash\");\n\n // Test with different domains but same paths\n const url1 = new URL(\"https://example.com/path?query=value#hash\");\n const url2 = new URL(\"https://different.com/path?query=value#hash\");\n expect(getRelativePart(url1)).toBe(getRelativePart(url2));\n});\n\n/**\n * A template literal tag that returns a URL.\n *\n * Any values passed are encoded.\n */\nexport function url(strings: TemplateStringsArray | readonly string[], ...values: (string | number | boolean)[]): URL {\n return new URL(urlString(strings, ...values));\n}\nundefined?.test(\"url\", ({ expect }) => {\n // Test with no interpolation\n expect(url`https://example.com`).toBeInstanceOf(URL);\n expect(url`https://example.com`.href).toBe(\"https://example.com/\");\n\n // Test with string interpolation\n expect(url`https://example.com/${\"path\"}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${\"path\"}`.pathname).toBe(\"/path\");\n\n // Test with number interpolation\n expect(url`https://example.com/${42}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${42}`.pathname).toBe(\"/42\");\n\n // Test with boolean interpolation\n expect(url`https://example.com/${true}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${true}`.pathname).toBe(\"/true\");\n\n // Test with special characters in interpolation\n expect(url`https://example.com/${\"path with spaces\"}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${\"path with spaces\"}`.pathname).toBe(\"/path%20with%20spaces\");\n\n // Test with multiple interpolations\n expect(url`https://example.com/${\"path\"}?query=${\"value\"}`).toBeInstanceOf(URL);\n expect(url`https://example.com/${\"path\"}?query=${\"value\"}`.pathname).toBe(\"/path\");\n expect(url`https://example.com/${\"path\"}?query=${\"value\"}`.search).toBe(\"?query=value\");\n});\n\n\n/**\n * A template literal tag that returns a URL string.\n *\n * Any values passed are encoded.\n */\nexport function urlString(strings: TemplateStringsArray | readonly string[], ...values: (string | number | boolean)[]): string {\n return templateIdentity(strings, ...values.map(encodeURIComponent));\n}\nundefined?.test(\"urlString\", ({ expect }) => {\n // Test with no interpolation\n expect(urlString`https://example.com`).toBe(\"https://example.com\");\n\n // Test with string interpolation\n expect(urlString`https://example.com/${\"path\"}`).toBe(\"https://example.com/path\");\n\n // Test with number interpolation\n expect(urlString`https://example.com/${42}`).toBe(\"https://example.com/42\");\n\n // Test with boolean interpolation\n expect(urlString`https://example.com/${true}`).toBe(\"https://example.com/true\");\n\n // Test with special characters in interpolation\n expect(urlString`https://example.com/${\"path with spaces\"}`).toBe(\"https://example.com/path%20with%20spaces\");\n expect(urlString`https://example.com/${\"?&=\"}`).toBe(\"https://example.com/%3F%26%3D\");\n\n // Test with multiple interpolations\n expect(urlString`https://example.com/${\"path\"}?query=${\"value\"}`).toBe(\"https://example.com/path?query=value\");\n expect(urlString`https://example.com/${\"path\"}?query=${\"value with spaces\"}`).toBe(\"https://example.com/path?query=value%20with%20spaces\");\n});\n\nexport function isChildUrl(parentUrl: URL, maybeChildUrl: URL) {\n return parentUrl.origin === maybeChildUrl.origin\n && isChildPath(parentUrl.pathname, maybeChildUrl.pathname)\n && [...parentUrl.searchParams].every(([key, value]) => maybeChildUrl.searchParams.get(key) === value)\n && (!parentUrl.hash || parentUrl.hash === maybeChildUrl.hash);\n}\nundefined?.test(\"isChildUrl\", ({ expect }) => {\n // true\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://abc.com/\"))).toBe(true);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://abc.com/path\"))).toBe(true);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://abc.com/path?query=value\"))).toBe(true);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://abc.com/path?query=value#hash\"))).toBe(true);\n\n // false\n expect(isChildUrl(new URL(\"https://abc.com\"), new URL(\"https://example.com\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://example.com/path\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://example.com/path?query=value\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://abc.com/\"), new URL(\"https://example.com/path?query=value#hash\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://example.com\"), new URL(\"https://abc.com/path?query=value#hash\"))).toBe(false);\n expect(isChildUrl(new URL(\"https://example.com?query=value123\"), new URL(\"https://example.com/path?query=value#hash\"))).toBe(false);\n});\n\nexport function isChildPath(parentPath: string, maybeChildPath: string) {\n parentPath = parentPath.endsWith(\"/\") ? parentPath : parentPath + \"/\";\n maybeChildPath = maybeChildPath.endsWith(\"/\") ? maybeChildPath : maybeChildPath + \"/\";\n return maybeChildPath.startsWith(parentPath);\n}\nundefined?.test(\"isSubPath\", ({ expect }) => {\n expect(isChildPath(\"/\", \"/\")).toBe(true);\n expect(isChildPath(\"/\", \"/path\")).toBe(true);\n expect(isChildPath(\"/path\", \"/\")).toBe(false);\n expect(isChildPath(\"/path\", \"/path\")).toBe(true);\n expect(isChildPath(\"/path/\", \"/path\")).toBe(true);\n expect(isChildPath(\"/path\", \"/path/\")).toBe(true);\n expect(isChildPath(\"/path/\", \"/path/\")).toBe(true);\n expect(isChildPath(\"/path\", \"/path/abc\")).toBe(true);\n expect(isChildPath(\"/path/\", \"/path/abc\")).toBe(true);\n expect(isChildPath(\"/path\", \"/path-abc\")).toBe(false);\n expect(isChildPath(\"/path\", \"/path-abc/\")).toBe(false);\n expect(isChildPath(\"/path/\", \"/path-abc\")).toBe(false);\n expect(isChildPath(\"/path/\", \"/path-abc/\")).toBe(false);\n});\n"],"mappings":"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","names":["url"]}
|
|
@@ -140,6 +140,12 @@ declare class StackAdminInterface extends StackServerInterface {
|
|
|
140
140
|
success: boolean;
|
|
141
141
|
error_message?: string;
|
|
142
142
|
}>;
|
|
143
|
+
sendTestWebhook(data: {
|
|
144
|
+
endpoint_id: string;
|
|
145
|
+
}): Promise<{
|
|
146
|
+
success: boolean;
|
|
147
|
+
error_message?: string;
|
|
148
|
+
}>;
|
|
143
149
|
listSentEmails(): Promise<InternalEmailsCrud["Admin"]["List"]>;
|
|
144
150
|
sendSignInInvitationEmail(email: string, callbackUrl: string): Promise<void>;
|
|
145
151
|
sendChatMessage(threadId: string, contextType: "email-theme" | "email-template" | "email-draft", messages: Array<{
|
|
@@ -140,6 +140,12 @@ declare class StackAdminInterface extends StackServerInterface {
|
|
|
140
140
|
success: boolean;
|
|
141
141
|
error_message?: string;
|
|
142
142
|
}>;
|
|
143
|
+
sendTestWebhook(data: {
|
|
144
|
+
endpoint_id: string;
|
|
145
|
+
}): Promise<{
|
|
146
|
+
success: boolean;
|
|
147
|
+
error_message?: string;
|
|
148
|
+
}>;
|
|
143
149
|
listSentEmails(): Promise<InternalEmailsCrud["Admin"]["List"]>;
|
|
144
150
|
sendSignInInvitationEmail(email: string, callbackUrl: string): Promise<void>;
|
|
145
151
|
sendChatMessage(threadId: string, contextType: "email-theme" | "email-template" | "email-draft", messages: Array<{
|
|
@@ -290,6 +290,16 @@ var StackAdminInterface = class extends import_server_interface.StackServerInter
|
|
|
290
290
|
}, null);
|
|
291
291
|
return await response.json();
|
|
292
292
|
}
|
|
293
|
+
async sendTestWebhook(data) {
|
|
294
|
+
const response = await this.sendAdminRequest(`/internal/send-test-webhook`, {
|
|
295
|
+
method: "POST",
|
|
296
|
+
headers: {
|
|
297
|
+
"content-type": "application/json"
|
|
298
|
+
},
|
|
299
|
+
body: JSON.stringify(data)
|
|
300
|
+
}, null);
|
|
301
|
+
return await response.json();
|
|
302
|
+
}
|
|
293
303
|
async listSentEmails() {
|
|
294
304
|
const response = await this.sendAdminRequest("/internal/emails", {
|
|
295
305
|
method: "GET"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/interface/admin-interface.ts"],"sourcesContent":["import { KnownErrors } from \"../known-errors\";\nimport { AccessToken, InternalSession, RefreshToken } from \"../sessions\";\nimport { Result } from \"../utils/results\";\nimport { ConfigCrud, ConfigOverrideCrud } from \"./crud/config\";\nimport { InternalEmailsCrud } from \"./crud/emails\";\nimport { InternalApiKeysCrud } from \"./crud/internal-api-keys\";\nimport { ProjectPermissionDefinitionsCrud } from \"./crud/project-permissions\";\nimport { ProjectsCrud } from \"./crud/projects\";\nimport { SvixTokenCrud } from \"./crud/svix-token\";\nimport { TeamPermissionDefinitionsCrud } from \"./crud/team-permissions\";\nimport type { AdminTransaction } from \"./crud/transactions\";\nimport { ServerAuthApplicationOptions, StackServerInterface } from \"./server-interface\";\n\n\nexport type ChatContent = Array<\n | { type: \"text\", text: string }\n | { type: \"tool-call\", toolName: string, toolCallId: string, args: any, argsText: string, result: any }\n>;\n\nexport type AdminAuthApplicationOptions = ServerAuthApplicationOptions &(\n | {\n superSecretAdminKey: string,\n }\n | {\n projectOwnerSession: InternalSession,\n }\n);\n\nexport type InternalApiKeyCreateCrudRequest = {\n has_publishable_client_key: boolean,\n has_secret_server_key: boolean,\n has_super_secret_admin_key: boolean,\n expires_at_millis: number,\n description: string,\n};\n\nexport type InternalApiKeyCreateCrudResponse = InternalApiKeysCrud[\"Admin\"][\"Read\"] & {\n publishable_client_key?: string,\n secret_server_key?: string,\n super_secret_admin_key?: string,\n};\n\nexport class StackAdminInterface extends StackServerInterface {\n constructor(public readonly options: AdminAuthApplicationOptions) {\n super(options);\n }\n\n public async sendAdminRequest(path: string, options: RequestInit, session: InternalSession | null, requestType: \"admin\" = \"admin\") {\n return await this.sendServerRequest(\n path,\n {\n ...options,\n headers: {\n \"x-stack-super-secret-admin-key\": \"superSecretAdminKey\" in this.options ? this.options.superSecretAdminKey : \"\",\n ...options.headers,\n },\n },\n session,\n requestType,\n );\n }\n\n protected async sendAdminRequestAndCatchKnownError<E extends typeof KnownErrors[keyof KnownErrors]>(\n path: string,\n requestOptions: RequestInit,\n tokenStoreOrNull: InternalSession | null,\n errorsToCatch: readonly E[],\n ): Promise<Result<\n Response & {\n usedTokens: {\n accessToken: AccessToken,\n refreshToken: RefreshToken | null,\n } | null,\n },\n InstanceType<E>\n >> {\n try {\n return Result.ok(await this.sendAdminRequest(path, requestOptions, tokenStoreOrNull));\n } catch (e) {\n for (const errorType of errorsToCatch) {\n if (errorType.isInstance(e)) {\n return Result.error(e as InstanceType<E>);\n }\n }\n throw e;\n }\n }\n\n async getProject(): Promise<ProjectsCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n \"/internal/projects/current\",\n {\n method: \"GET\",\n },\n null,\n );\n return await response.json();\n }\n\n async updateProject(update: ProjectsCrud[\"Admin\"][\"Update\"]): Promise<ProjectsCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n \"/internal/projects/current\",\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(update),\n },\n null,\n );\n return await response.json();\n }\n\n async createInternalApiKey(\n options: InternalApiKeyCreateCrudRequest,\n ): Promise<InternalApiKeyCreateCrudResponse> {\n const response = await this.sendAdminRequest(\n \"/internal/api-keys\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(options),\n },\n null,\n );\n return await response.json();\n }\n\n async listInternalApiKeys(): Promise<InternalApiKeysCrud[\"Admin\"][\"Read\"][]> {\n const response = await this.sendAdminRequest(\"/internal/api-keys\", {}, null);\n const result = await response.json() as InternalApiKeysCrud[\"Admin\"][\"List\"];\n return result.items;\n }\n\n async revokeInternalApiKeyById(id: string) {\n await this.sendAdminRequest(\n `/internal/api-keys/${id}`, {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n revoked: true,\n }),\n },\n null,\n );\n }\n\n async getInternalApiKey(id: string, session: InternalSession): Promise<InternalApiKeysCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(`/internal/api-keys/${id}`, {}, session);\n return await response.json();\n }\n\n async listInternalEmailTemplates(): Promise<{ id: string, display_name: string, theme_id?: string, tsx_source: string }[]> {\n const response = await this.sendAdminRequest(`/internal/email-templates`, {}, null);\n const result = await response.json() as { templates: { id: string, display_name: string, theme_id?: string, tsx_source: string }[] };\n return result.templates;\n }\n\n async listInternalEmailDrafts(): Promise<{ id: string, display_name: string, theme_id?: string | undefined | false, tsx_source: string, sent_at_millis?: number | null }[]> {\n const response = await this.sendAdminRequest(`/internal/email-drafts`, {}, null);\n const result = await response.json() as { drafts: { id: string, display_name: string, theme_id?: string | undefined | false, tsx_source: string, sent_at_millis?: number | null }[] };\n return result.drafts;\n }\n\n async createEmailDraft(options: { display_name?: string, theme_id?: string | false, tsx_source?: string }): Promise<{ id: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-drafts`,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(options),\n },\n null,\n );\n return await response.json();\n }\n\n async updateEmailDraft(id: string, data: { display_name?: string, theme_id?: string | null | false, tsx_source?: string, sent_at_millis?: number | null }): Promise<void> {\n await this.sendAdminRequest(\n `/internal/email-drafts/${id}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n }\n\n async listEmailThemes(): Promise<{ id: string, display_name: string }[]> {\n const response = await this.sendAdminRequest(`/internal/email-themes`, {}, null);\n const result = await response.json() as { themes: { id: string, display_name: string }[] };\n return result.themes;\n }\n\n\n // Team permission definitions methods\n async listTeamPermissionDefinitions(): Promise<TeamPermissionDefinitionsCrud['Admin']['Read'][]> {\n const response = await this.sendAdminRequest(`/team-permission-definitions`, {}, null);\n const result = await response.json() as TeamPermissionDefinitionsCrud['Admin']['List'];\n return result.items;\n }\n\n async createTeamPermissionDefinition(data: TeamPermissionDefinitionsCrud['Admin']['Create']): Promise<TeamPermissionDefinitionsCrud['Admin']['Read']> {\n const response = await this.sendAdminRequest(\n \"/team-permission-definitions\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n return await response.json();\n }\n\n async updateTeamPermissionDefinition(permissionId: string, data: TeamPermissionDefinitionsCrud['Admin']['Update']): Promise<TeamPermissionDefinitionsCrud['Admin']['Read']> {\n const response = await this.sendAdminRequest(\n `/team-permission-definitions/${permissionId}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n return await response.json();\n }\n\n async deleteTeamPermissionDefinition(permissionId: string): Promise<void> {\n await this.sendAdminRequest(\n `/team-permission-definitions/${permissionId}`,\n { method: \"DELETE\" },\n null,\n );\n }\n\n async listProjectPermissionDefinitions(): Promise<ProjectPermissionDefinitionsCrud['Admin']['Read'][]> {\n const response = await this.sendAdminRequest(`/project-permission-definitions`, {}, null);\n const result = await response.json() as ProjectPermissionDefinitionsCrud['Admin']['List'];\n return result.items;\n }\n\n async createProjectPermissionDefinition(data: ProjectPermissionDefinitionsCrud['Admin']['Create']): Promise<ProjectPermissionDefinitionsCrud['Admin']['Read']> {\n const response = await this.sendAdminRequest(\n \"/project-permission-definitions\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n return await response.json();\n }\n\n async updateProjectPermissionDefinition(permissionId: string, data: ProjectPermissionDefinitionsCrud['Admin']['Update']): Promise<ProjectPermissionDefinitionsCrud['Admin']['Read']> {\n const response = await this.sendAdminRequest(\n `/project-permission-definitions/${permissionId}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n return await response.json();\n }\n\n async deleteProjectPermissionDefinition(permissionId: string): Promise<void> {\n await this.sendAdminRequest(\n `/project-permission-definitions/${permissionId}`,\n { method: \"DELETE\" },\n null,\n );\n }\n\n async getSvixToken(): Promise<SvixTokenCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n \"/webhooks/svix-token\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({}),\n },\n null,\n );\n return await response.json();\n }\n\n async deleteProject(): Promise<void> {\n await this.sendAdminRequest(\n \"/internal/projects/current\",\n {\n method: \"DELETE\",\n },\n null,\n );\n }\n\n async getMetrics(includeAnonymous: boolean = false): Promise<any> {\n const params = new URLSearchParams();\n if (includeAnonymous) {\n params.append('include_anonymous', 'true');\n }\n const queryString = params.toString();\n const response = await this.sendAdminRequest(\n `/internal/metrics${queryString ? `?${queryString}` : ''}`,\n {\n method: \"GET\",\n },\n null,\n );\n return await response.json();\n }\n\n async sendTestEmail(data: {\n recipient_email: string,\n email_config: {\n host: string,\n port: number,\n username: string,\n password: string,\n sender_email: string,\n sender_name: string,\n },\n }): Promise<{ success: boolean, error_message?: string }> {\n const response = await this.sendAdminRequest(`/internal/send-test-email`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n }, null);\n return await response.json();\n }\n\n async listSentEmails(): Promise<InternalEmailsCrud[\"Admin\"][\"List\"]> {\n const response = await this.sendAdminRequest(\"/internal/emails\", {\n method: \"GET\",\n }, null);\n return await response.json();\n }\n\n async sendSignInInvitationEmail(\n email: string,\n callbackUrl: string,\n ): Promise<void> {\n await this.sendAdminRequest(\n \"/internal/send-sign-in-invitation\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({\n email,\n callback_url: callbackUrl,\n }),\n },\n null,\n );\n }\n\n\n async sendChatMessage(\n threadId: string,\n contextType: \"email-theme\" | \"email-template\" | \"email-draft\",\n messages: Array<{ role: string, content: any }>,\n abortSignal?: AbortSignal,\n ): Promise<{ content: ChatContent }> {\n const response = await this.sendAdminRequest(\n `/internal/ai-chat/${threadId}`,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ context_type: contextType, messages }),\n signal: abortSignal,\n },\n null,\n );\n return await response.json();\n }\n\n async saveChatMessage(threadId: string, message: any): Promise<void> {\n await this.sendAdminRequest(\n `/internal/ai-chat/${threadId}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ message }),\n },\n null,\n );\n }\n\n async listChatMessages(threadId: string): Promise<{ messages: Array<any> }> {\n const response = await this.sendAdminRequest(\n `/internal/ai-chat/${threadId}`,\n { method: \"GET\" },\n null,\n );\n return await response.json();\n }\n\n async renderEmailPreview(options: { themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string }): Promise<{ html: string }> {\n const response = await this.sendAdminRequest(`/emails/render-email`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n theme_id: options.themeId,\n theme_tsx_source: options.themeTsxSource,\n template_id: options.templateId,\n template_tsx_source: options.templateTsxSource,\n }),\n }, null);\n return await response.json();\n }\n\n async createEmailTheme(displayName: string): Promise<{ id: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-themes`,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n display_name: displayName,\n }),\n },\n null,\n );\n return await response.json();\n }\n\n async getEmailTheme(id: string): Promise<{ display_name: string, tsx_source: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-themes/${id}`,\n { method: \"GET\" },\n null,\n );\n return await response.json();\n }\n\n async updateEmailTheme(id: string, tsxSource: string): Promise<void> {\n await this.sendAdminRequest(\n `/internal/email-themes/${id}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n tsx_source: tsxSource,\n }),\n },\n null,\n );\n }\n\n async updateEmailTemplate(id: string, tsxSource: string, themeId: string | null | false): Promise<{ rendered_html: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-templates/${id}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ tsx_source: tsxSource, theme_id: themeId }),\n },\n null,\n );\n return await response.json();\n }\n\n async getConfig(): Promise<ConfigCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n `/internal/config`,\n { method: \"GET\" },\n null,\n );\n return await response.json();\n }\n\n async updateConfig(data: { configOverride: any }): Promise<ConfigOverrideCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n `/internal/config/override`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ config_override_string: JSON.stringify(data.configOverride) }),\n },\n null,\n );\n return await response.json();\n }\n async createEmailTemplate(displayName: string): Promise<{ id: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-templates`,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n display_name: displayName,\n }),\n },\n null,\n );\n return await response.json();\n }\n\n async setupPayments(): Promise<{ url: string }> {\n const response = await this.sendAdminRequest(\n \"/internal/payments/setup\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({}),\n },\n null,\n );\n return await response.json();\n }\n\n async getStripeAccountInfo(): Promise<null | { account_id: string, charges_enabled: boolean, details_submitted: boolean, payouts_enabled: boolean }> {\n const response = await this.sendAdminRequestAndCatchKnownError(\n \"/internal/payments/stripe/account-info\",\n {},\n null,\n [KnownErrors.StripeAccountInfoNotFound],\n );\n if (response.status === \"error\") {\n return null;\n }\n return await response.data.json();\n }\n\n async createStripeWidgetAccountSession(): Promise<{ client_secret: string }> {\n const response = await this.sendAdminRequest(\n \"/internal/payments/stripe-widgets/account-session\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({}),\n },\n null,\n );\n return await response.json();\n }\n\n async listTransactions(params?: { cursor?: string, limit?: number, type?: 'subscription' | 'one_time' | 'item_quantity_change', customerType?: 'user' | 'team' | 'custom' }): Promise<{ transactions: AdminTransaction[], nextCursor: string | null }> {\n const qs = new URLSearchParams();\n if (params?.cursor) qs.set('cursor', params.cursor);\n if (typeof params?.limit === 'number') qs.set('limit', String(params.limit));\n if (params?.type) qs.set('type', params.type);\n if (params?.customerType) qs.set('customer_type', params.customerType);\n const response = await this.sendAdminRequest(\n `/internal/payments/transactions${qs.size ? `?${qs.toString()}` : ''}`,\n { method: 'GET' },\n null,\n );\n const json = await response.json() as { transactions: AdminTransaction[], next_cursor: string | null };\n return { transactions: json.transactions, nextCursor: json.next_cursor };\n }\n\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAA4B;AAE5B,qBAAuB;AASvB,8BAAmE;AA+B5D,IAAM,sBAAN,cAAkC,6CAAqB;AAAA,EAC5D,YAA4B,SAAsC;AAChE,UAAM,OAAO;AADa;AAAA,EAE5B;AAAA,EAEA,MAAa,iBAAiB,MAAc,SAAsB,SAAiC,cAAuB,SAAS;AACjI,WAAO,MAAM,KAAK;AAAA,MAChB;AAAA,MACA;AAAA,QACE,GAAG;AAAA,QACH,SAAS;AAAA,UACP,kCAAkC,yBAAyB,KAAK,UAAU,KAAK,QAAQ,sBAAsB;AAAA,UAC7G,GAAG,QAAQ;AAAA,QACb;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAgB,mCACd,MACA,gBACA,kBACA,eASC;AACD,QAAI;AACF,aAAO,sBAAO,GAAG,MAAM,KAAK,iBAAiB,MAAM,gBAAgB,gBAAgB,CAAC;AAAA,IACtF,SAAS,GAAG;AACV,iBAAW,aAAa,eAAe;AACrC,YAAI,UAAU,WAAW,CAAC,GAAG;AAC3B,iBAAO,sBAAO,MAAM,CAAoB;AAAA,QAC1C;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,aAAqD;AACzD,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,cAAc,QAAiF;AACnG,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,MAAM;AAAA,MAC7B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,qBACJ,SAC2C;AAC3C,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,sBAAuE;AAC3E,UAAM,WAAW,MAAM,KAAK,iBAAiB,sBAAsB,CAAC,GAAG,IAAI;AAC3E,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,yBAAyB,IAAY;AACzC,UAAM,KAAK;AAAA,MACT,sBAAsB,EAAE;AAAA,MAAI;AAAA,QAC1B,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,IAAY,SAAyE;AAC3G,UAAM,WAAW,MAAM,KAAK,iBAAiB,sBAAsB,EAAE,IAAI,CAAC,GAAG,OAAO;AACpF,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,6BAAqH;AACzH,UAAM,WAAW,MAAM,KAAK,iBAAiB,6BAA6B,CAAC,GAAG,IAAI;AAClF,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,0BAAsK;AAC1K,UAAM,WAAW,MAAM,KAAK,iBAAiB,0BAA0B,CAAC,GAAG,IAAI;AAC/E,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,iBAAiB,SAA6G;AAClI,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,iBAAiB,IAAY,MAAuI;AACxK,UAAM,KAAK;AAAA,MACT,0BAA0B,EAAE;AAAA,MAC5B;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,kBAAmE;AACvE,UAAM,WAAW,MAAM,KAAK,iBAAiB,0BAA0B,CAAC,GAAG,IAAI;AAC/E,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA,EAIA,MAAM,gCAA2F;AAC/F,UAAM,WAAW,MAAM,KAAK,iBAAiB,gCAAgC,CAAC,GAAG,IAAI;AACrF,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,+BAA+B,MAAiH;AACpJ,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,+BAA+B,cAAsB,MAAiH;AAC1K,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,gCAAgC,YAAY;AAAA,MAC5C;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,+BAA+B,cAAqC;AACxE,UAAM,KAAK;AAAA,MACT,gCAAgC,YAAY;AAAA,MAC5C,EAAE,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,mCAAiG;AACrG,UAAM,WAAW,MAAM,KAAK,iBAAiB,mCAAmC,CAAC,GAAG,IAAI;AACxF,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,kCAAkC,MAAuH;AAC7J,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,kCAAkC,cAAsB,MAAuH;AACnL,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,mCAAmC,YAAY;AAAA,MAC/C;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,IAAI;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,kCAAkC,cAAqC;AAC3E,UAAM,KAAK;AAAA,MACT,mCAAmC,YAAY;AAAA,MAC/C,EAAE,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eAAwD;AAC5D,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,gBAA+B;AACnC,UAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,mBAA4B,OAAqB;AAChE,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,kBAAkB;AACpB,aAAO,OAAO,qBAAqB,MAAM;AAAA,IAC3C;AACA,UAAM,cAAc,OAAO,SAAS;AACpC,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,oBAAoB,cAAc,IAAI,WAAW,KAAK,EAAE;AAAA,MACxD;AAAA,QACE,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,cAAc,MAUsC;AACxD,UAAM,WAAW,MAAM,KAAK,iBAAiB,6BAA6B;AAAA,MACxE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,GAAG,IAAI;AACP,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,iBAA+D;AACnE,UAAM,WAAW,MAAM,KAAK,iBAAiB,oBAAoB;AAAA,MAC/D,QAAQ;AAAA,IACV,GAAG,IAAI;AACP,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,0BACJ,OACA,aACe;AACf,UAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB;AAAA,UACA,cAAc;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAGA,MAAM,gBACJ,UACA,aACA,UACA,aACmC;AACnC,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,qBAAqB,QAAQ;AAAA,MAC7B;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,cAAc,aAAa,SAAS,CAAC;AAAA,QAC5D,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,gBAAgB,UAAkB,SAA6B;AACnE,UAAM,KAAK;AAAA,MACT,qBAAqB,QAAQ;AAAA,MAC7B;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,MAClC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,UAAqD;AAC1E,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,qBAAqB,QAAQ;AAAA,MAC7B,EAAE,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,mBAAmB,SAAmJ;AAC1K,UAAM,WAAW,MAAM,KAAK,iBAAiB,wBAAwB;AAAA,MACnE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,UAAU,QAAQ;AAAA,QAClB,kBAAkB,QAAQ;AAAA,QAC1B,aAAa,QAAQ;AAAA,QACrB,qBAAqB,QAAQ;AAAA,MAC/B,CAAC;AAAA,IACH,GAAG,IAAI;AACP,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,iBAAiB,aAA8C;AACnE,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,cAAc;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,cAAc,IAAmE;AACrF,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,0BAA0B,EAAE;AAAA,MAC5B,EAAE,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,iBAAiB,IAAY,WAAkC;AACnE,UAAM,KAAK;AAAA,MACT,0BAA0B,EAAE;AAAA,MAC5B;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,IAAY,WAAmB,SAAoE;AAC3H,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,6BAA6B,EAAE;AAAA,MAC/B;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,YAAY,WAAW,UAAU,QAAQ,CAAC;AAAA,MACnE;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,YAAkD;AACtD,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA,EAAE,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,aAAa,MAA6E;AAC9F,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,wBAAwB,KAAK,UAAU,KAAK,cAAc,EAAE,CAAC;AAAA,MACtF;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EACA,MAAM,oBAAoB,aAA8C;AACtE,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,cAAc;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,gBAA0C;AAC9C,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,uBAA+I;AACnJ,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA,CAAC;AAAA,MACD;AAAA,MACA,CAAC,gCAAY,yBAAyB;AAAA,IACxC;AACA,QAAI,SAAS,WAAW,SAAS;AAC/B,aAAO;AAAA,IACT;AACA,WAAO,MAAM,SAAS,KAAK,KAAK;AAAA,EAClC;AAAA,EAEA,MAAM,mCAAuE;AAC3E,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,iBAAiB,QAAgO;AACrP,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,QAAQ,OAAQ,IAAG,IAAI,UAAU,OAAO,MAAM;AAClD,QAAI,OAAO,QAAQ,UAAU,SAAU,IAAG,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAC3E,QAAI,QAAQ,KAAM,IAAG,IAAI,QAAQ,OAAO,IAAI;AAC5C,QAAI,QAAQ,aAAc,IAAG,IAAI,iBAAiB,OAAO,YAAY;AACrE,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,kCAAkC,GAAG,OAAO,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE;AAAA,MACpE,EAAE,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AACA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO,EAAE,cAAc,KAAK,cAAc,YAAY,KAAK,YAAY;AAAA,EACzE;AAEF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/interface/admin-interface.ts"],"sourcesContent":["import { KnownErrors } from \"../known-errors\";\nimport { AccessToken, InternalSession, RefreshToken } from \"../sessions\";\nimport { Result } from \"../utils/results\";\nimport { ConfigCrud, ConfigOverrideCrud } from \"./crud/config\";\nimport { InternalEmailsCrud } from \"./crud/emails\";\nimport { InternalApiKeysCrud } from \"./crud/internal-api-keys\";\nimport { ProjectPermissionDefinitionsCrud } from \"./crud/project-permissions\";\nimport { ProjectsCrud } from \"./crud/projects\";\nimport { SvixTokenCrud } from \"./crud/svix-token\";\nimport { TeamPermissionDefinitionsCrud } from \"./crud/team-permissions\";\nimport type { AdminTransaction } from \"./crud/transactions\";\nimport { ServerAuthApplicationOptions, StackServerInterface } from \"./server-interface\";\n\n\nexport type ChatContent = Array<\n | { type: \"text\", text: string }\n | { type: \"tool-call\", toolName: string, toolCallId: string, args: any, argsText: string, result: any }\n>;\n\nexport type AdminAuthApplicationOptions = ServerAuthApplicationOptions &(\n | {\n superSecretAdminKey: string,\n }\n | {\n projectOwnerSession: InternalSession,\n }\n);\n\nexport type InternalApiKeyCreateCrudRequest = {\n has_publishable_client_key: boolean,\n has_secret_server_key: boolean,\n has_super_secret_admin_key: boolean,\n expires_at_millis: number,\n description: string,\n};\n\nexport type InternalApiKeyCreateCrudResponse = InternalApiKeysCrud[\"Admin\"][\"Read\"] & {\n publishable_client_key?: string,\n secret_server_key?: string,\n super_secret_admin_key?: string,\n};\n\nexport class StackAdminInterface extends StackServerInterface {\n constructor(public readonly options: AdminAuthApplicationOptions) {\n super(options);\n }\n\n public async sendAdminRequest(path: string, options: RequestInit, session: InternalSession | null, requestType: \"admin\" = \"admin\") {\n return await this.sendServerRequest(\n path,\n {\n ...options,\n headers: {\n \"x-stack-super-secret-admin-key\": \"superSecretAdminKey\" in this.options ? this.options.superSecretAdminKey : \"\",\n ...options.headers,\n },\n },\n session,\n requestType,\n );\n }\n\n protected async sendAdminRequestAndCatchKnownError<E extends typeof KnownErrors[keyof KnownErrors]>(\n path: string,\n requestOptions: RequestInit,\n tokenStoreOrNull: InternalSession | null,\n errorsToCatch: readonly E[],\n ): Promise<Result<\n Response & {\n usedTokens: {\n accessToken: AccessToken,\n refreshToken: RefreshToken | null,\n } | null,\n },\n InstanceType<E>\n >> {\n try {\n return Result.ok(await this.sendAdminRequest(path, requestOptions, tokenStoreOrNull));\n } catch (e) {\n for (const errorType of errorsToCatch) {\n if (errorType.isInstance(e)) {\n return Result.error(e as InstanceType<E>);\n }\n }\n throw e;\n }\n }\n\n async getProject(): Promise<ProjectsCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n \"/internal/projects/current\",\n {\n method: \"GET\",\n },\n null,\n );\n return await response.json();\n }\n\n async updateProject(update: ProjectsCrud[\"Admin\"][\"Update\"]): Promise<ProjectsCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n \"/internal/projects/current\",\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(update),\n },\n null,\n );\n return await response.json();\n }\n\n async createInternalApiKey(\n options: InternalApiKeyCreateCrudRequest,\n ): Promise<InternalApiKeyCreateCrudResponse> {\n const response = await this.sendAdminRequest(\n \"/internal/api-keys\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(options),\n },\n null,\n );\n return await response.json();\n }\n\n async listInternalApiKeys(): Promise<InternalApiKeysCrud[\"Admin\"][\"Read\"][]> {\n const response = await this.sendAdminRequest(\"/internal/api-keys\", {}, null);\n const result = await response.json() as InternalApiKeysCrud[\"Admin\"][\"List\"];\n return result.items;\n }\n\n async revokeInternalApiKeyById(id: string) {\n await this.sendAdminRequest(\n `/internal/api-keys/${id}`, {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n revoked: true,\n }),\n },\n null,\n );\n }\n\n async getInternalApiKey(id: string, session: InternalSession): Promise<InternalApiKeysCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(`/internal/api-keys/${id}`, {}, session);\n return await response.json();\n }\n\n async listInternalEmailTemplates(): Promise<{ id: string, display_name: string, theme_id?: string, tsx_source: string }[]> {\n const response = await this.sendAdminRequest(`/internal/email-templates`, {}, null);\n const result = await response.json() as { templates: { id: string, display_name: string, theme_id?: string, tsx_source: string }[] };\n return result.templates;\n }\n\n async listInternalEmailDrafts(): Promise<{ id: string, display_name: string, theme_id?: string | undefined | false, tsx_source: string, sent_at_millis?: number | null }[]> {\n const response = await this.sendAdminRequest(`/internal/email-drafts`, {}, null);\n const result = await response.json() as { drafts: { id: string, display_name: string, theme_id?: string | undefined | false, tsx_source: string, sent_at_millis?: number | null }[] };\n return result.drafts;\n }\n\n async createEmailDraft(options: { display_name?: string, theme_id?: string | false, tsx_source?: string }): Promise<{ id: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-drafts`,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(options),\n },\n null,\n );\n return await response.json();\n }\n\n async updateEmailDraft(id: string, data: { display_name?: string, theme_id?: string | null | false, tsx_source?: string, sent_at_millis?: number | null }): Promise<void> {\n await this.sendAdminRequest(\n `/internal/email-drafts/${id}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n }\n\n async listEmailThemes(): Promise<{ id: string, display_name: string }[]> {\n const response = await this.sendAdminRequest(`/internal/email-themes`, {}, null);\n const result = await response.json() as { themes: { id: string, display_name: string }[] };\n return result.themes;\n }\n\n\n // Team permission definitions methods\n async listTeamPermissionDefinitions(): Promise<TeamPermissionDefinitionsCrud['Admin']['Read'][]> {\n const response = await this.sendAdminRequest(`/team-permission-definitions`, {}, null);\n const result = await response.json() as TeamPermissionDefinitionsCrud['Admin']['List'];\n return result.items;\n }\n\n async createTeamPermissionDefinition(data: TeamPermissionDefinitionsCrud['Admin']['Create']): Promise<TeamPermissionDefinitionsCrud['Admin']['Read']> {\n const response = await this.sendAdminRequest(\n \"/team-permission-definitions\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n return await response.json();\n }\n\n async updateTeamPermissionDefinition(permissionId: string, data: TeamPermissionDefinitionsCrud['Admin']['Update']): Promise<TeamPermissionDefinitionsCrud['Admin']['Read']> {\n const response = await this.sendAdminRequest(\n `/team-permission-definitions/${permissionId}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n return await response.json();\n }\n\n async deleteTeamPermissionDefinition(permissionId: string): Promise<void> {\n await this.sendAdminRequest(\n `/team-permission-definitions/${permissionId}`,\n { method: \"DELETE\" },\n null,\n );\n }\n\n async listProjectPermissionDefinitions(): Promise<ProjectPermissionDefinitionsCrud['Admin']['Read'][]> {\n const response = await this.sendAdminRequest(`/project-permission-definitions`, {}, null);\n const result = await response.json() as ProjectPermissionDefinitionsCrud['Admin']['List'];\n return result.items;\n }\n\n async createProjectPermissionDefinition(data: ProjectPermissionDefinitionsCrud['Admin']['Create']): Promise<ProjectPermissionDefinitionsCrud['Admin']['Read']> {\n const response = await this.sendAdminRequest(\n \"/project-permission-definitions\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n return await response.json();\n }\n\n async updateProjectPermissionDefinition(permissionId: string, data: ProjectPermissionDefinitionsCrud['Admin']['Update']): Promise<ProjectPermissionDefinitionsCrud['Admin']['Read']> {\n const response = await this.sendAdminRequest(\n `/project-permission-definitions/${permissionId}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n },\n null,\n );\n return await response.json();\n }\n\n async deleteProjectPermissionDefinition(permissionId: string): Promise<void> {\n await this.sendAdminRequest(\n `/project-permission-definitions/${permissionId}`,\n { method: \"DELETE\" },\n null,\n );\n }\n\n async getSvixToken(): Promise<SvixTokenCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n \"/webhooks/svix-token\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({}),\n },\n null,\n );\n return await response.json();\n }\n\n async deleteProject(): Promise<void> {\n await this.sendAdminRequest(\n \"/internal/projects/current\",\n {\n method: \"DELETE\",\n },\n null,\n );\n }\n\n async getMetrics(includeAnonymous: boolean = false): Promise<any> {\n const params = new URLSearchParams();\n if (includeAnonymous) {\n params.append('include_anonymous', 'true');\n }\n const queryString = params.toString();\n const response = await this.sendAdminRequest(\n `/internal/metrics${queryString ? `?${queryString}` : ''}`,\n {\n method: \"GET\",\n },\n null,\n );\n return await response.json();\n }\n\n async sendTestEmail(data: {\n recipient_email: string,\n email_config: {\n host: string,\n port: number,\n username: string,\n password: string,\n sender_email: string,\n sender_name: string,\n },\n }): Promise<{ success: boolean, error_message?: string }> {\n const response = await this.sendAdminRequest(`/internal/send-test-email`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n }, null);\n return await response.json();\n }\n\n async sendTestWebhook(data: {\n endpoint_id: string,\n }): Promise<{ success: boolean, error_message?: string }> {\n const response = await this.sendAdminRequest(`/internal/send-test-webhook`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(data),\n }, null);\n return await response.json();\n }\n\n async listSentEmails(): Promise<InternalEmailsCrud[\"Admin\"][\"List\"]> {\n const response = await this.sendAdminRequest(\"/internal/emails\", {\n method: \"GET\",\n }, null);\n return await response.json();\n }\n\n async sendSignInInvitationEmail(\n email: string,\n callbackUrl: string,\n ): Promise<void> {\n await this.sendAdminRequest(\n \"/internal/send-sign-in-invitation\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({\n email,\n callback_url: callbackUrl,\n }),\n },\n null,\n );\n }\n\n\n async sendChatMessage(\n threadId: string,\n contextType: \"email-theme\" | \"email-template\" | \"email-draft\",\n messages: Array<{ role: string, content: any }>,\n abortSignal?: AbortSignal,\n ): Promise<{ content: ChatContent }> {\n const response = await this.sendAdminRequest(\n `/internal/ai-chat/${threadId}`,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ context_type: contextType, messages }),\n signal: abortSignal,\n },\n null,\n );\n return await response.json();\n }\n\n async saveChatMessage(threadId: string, message: any): Promise<void> {\n await this.sendAdminRequest(\n `/internal/ai-chat/${threadId}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ message }),\n },\n null,\n );\n }\n\n async listChatMessages(threadId: string): Promise<{ messages: Array<any> }> {\n const response = await this.sendAdminRequest(\n `/internal/ai-chat/${threadId}`,\n { method: \"GET\" },\n null,\n );\n return await response.json();\n }\n\n async renderEmailPreview(options: { themeId?: string | null | false, themeTsxSource?: string, templateId?: string, templateTsxSource?: string }): Promise<{ html: string }> {\n const response = await this.sendAdminRequest(`/emails/render-email`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n theme_id: options.themeId,\n theme_tsx_source: options.themeTsxSource,\n template_id: options.templateId,\n template_tsx_source: options.templateTsxSource,\n }),\n }, null);\n return await response.json();\n }\n\n async createEmailTheme(displayName: string): Promise<{ id: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-themes`,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n display_name: displayName,\n }),\n },\n null,\n );\n return await response.json();\n }\n\n async getEmailTheme(id: string): Promise<{ display_name: string, tsx_source: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-themes/${id}`,\n { method: \"GET\" },\n null,\n );\n return await response.json();\n }\n\n async updateEmailTheme(id: string, tsxSource: string): Promise<void> {\n await this.sendAdminRequest(\n `/internal/email-themes/${id}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n tsx_source: tsxSource,\n }),\n },\n null,\n );\n }\n\n async updateEmailTemplate(id: string, tsxSource: string, themeId: string | null | false): Promise<{ rendered_html: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-templates/${id}`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ tsx_source: tsxSource, theme_id: themeId }),\n },\n null,\n );\n return await response.json();\n }\n\n async getConfig(): Promise<ConfigCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n `/internal/config`,\n { method: \"GET\" },\n null,\n );\n return await response.json();\n }\n\n async updateConfig(data: { configOverride: any }): Promise<ConfigOverrideCrud[\"Admin\"][\"Read\"]> {\n const response = await this.sendAdminRequest(\n `/internal/config/override`,\n {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({ config_override_string: JSON.stringify(data.configOverride) }),\n },\n null,\n );\n return await response.json();\n }\n async createEmailTemplate(displayName: string): Promise<{ id: string }> {\n const response = await this.sendAdminRequest(\n `/internal/email-templates`,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n display_name: displayName,\n }),\n },\n null,\n );\n return await response.json();\n }\n\n async setupPayments(): Promise<{ url: string }> {\n const response = await this.sendAdminRequest(\n \"/internal/payments/setup\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({}),\n },\n null,\n );\n return await response.json();\n }\n\n async getStripeAccountInfo(): Promise<null | { account_id: string, charges_enabled: boolean, details_submitted: boolean, payouts_enabled: boolean }> {\n const response = await this.sendAdminRequestAndCatchKnownError(\n \"/internal/payments/stripe/account-info\",\n {},\n null,\n [KnownErrors.StripeAccountInfoNotFound],\n );\n if (response.status === \"error\") {\n return null;\n }\n return await response.data.json();\n }\n\n async createStripeWidgetAccountSession(): Promise<{ client_secret: string }> {\n const response = await this.sendAdminRequest(\n \"/internal/payments/stripe-widgets/account-session\",\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({}),\n },\n null,\n );\n return await response.json();\n }\n\n async listTransactions(params?: { cursor?: string, limit?: number, type?: 'subscription' | 'one_time' | 'item_quantity_change', customerType?: 'user' | 'team' | 'custom' }): Promise<{ transactions: AdminTransaction[], nextCursor: string | null }> {\n const qs = new URLSearchParams();\n if (params?.cursor) qs.set('cursor', params.cursor);\n if (typeof params?.limit === 'number') qs.set('limit', String(params.limit));\n if (params?.type) qs.set('type', params.type);\n if (params?.customerType) qs.set('customer_type', params.customerType);\n const response = await this.sendAdminRequest(\n `/internal/payments/transactions${qs.size ? `?${qs.toString()}` : ''}`,\n { method: 'GET' },\n null,\n );\n const json = await response.json() as { transactions: AdminTransaction[], next_cursor: string | null };\n return { transactions: json.transactions, nextCursor: json.next_cursor };\n }\n\n}\n"],"mappings":"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","names":[]}
|
|
@@ -40,17 +40,18 @@ type ClientInterfaceOptions = {
|
|
|
40
40
|
});
|
|
41
41
|
declare class StackClientInterface {
|
|
42
42
|
readonly options: ClientInterfaceOptions;
|
|
43
|
+
private pendingNetworkDiagnostics?;
|
|
43
44
|
constructor(options: ClientInterfaceOptions);
|
|
44
45
|
get projectId(): string;
|
|
45
46
|
getApiUrl(): string;
|
|
46
47
|
runNetworkDiagnostics(session?: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<{
|
|
47
48
|
"navigator?.onLine": any;
|
|
48
49
|
cfTrace: string;
|
|
49
|
-
apiRoot: string;
|
|
50
50
|
baseUrlBackend: string;
|
|
51
51
|
prodDashboard: string;
|
|
52
52
|
prodBackend: string;
|
|
53
53
|
}>;
|
|
54
|
+
private _runNetworkDiagnosticsInner;
|
|
54
55
|
protected _createNetworkError(cause: Error, session?: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<Error>;
|
|
55
56
|
protected _networkRetry<T>(cb: () => Promise<Result<T, any>>, session?: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<T>;
|
|
56
57
|
protected _networkRetryException<T>(cb: () => Promise<T>, session?: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<T>;
|
|
@@ -128,7 +129,7 @@ declare class StackClientInterface {
|
|
|
128
129
|
accessToken: string;
|
|
129
130
|
refreshToken: string;
|
|
130
131
|
}, KnownErrors["EmailPasswordMismatch"]>>;
|
|
131
|
-
signUpWithCredential(email: string, password: string, emailVerificationRedirectUrl: string, session: InternalSession): Promise<Result<{
|
|
132
|
+
signUpWithCredential(email: string, password: string, emailVerificationRedirectUrl: string | undefined, session: InternalSession): Promise<Result<{
|
|
132
133
|
accessToken: string;
|
|
133
134
|
refreshToken: string;
|
|
134
135
|
}, KnownErrors["UserWithEmailAlreadyExists"] | KnownErrors["PasswordRequirementsNotMet"]>>;
|
|
@@ -40,17 +40,18 @@ type ClientInterfaceOptions = {
|
|
|
40
40
|
});
|
|
41
41
|
declare class StackClientInterface {
|
|
42
42
|
readonly options: ClientInterfaceOptions;
|
|
43
|
+
private pendingNetworkDiagnostics?;
|
|
43
44
|
constructor(options: ClientInterfaceOptions);
|
|
44
45
|
get projectId(): string;
|
|
45
46
|
getApiUrl(): string;
|
|
46
47
|
runNetworkDiagnostics(session?: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<{
|
|
47
48
|
"navigator?.onLine": any;
|
|
48
49
|
cfTrace: string;
|
|
49
|
-
apiRoot: string;
|
|
50
50
|
baseUrlBackend: string;
|
|
51
51
|
prodDashboard: string;
|
|
52
52
|
prodBackend: string;
|
|
53
53
|
}>;
|
|
54
|
+
private _runNetworkDiagnosticsInner;
|
|
54
55
|
protected _createNetworkError(cause: Error, session?: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<Error>;
|
|
55
56
|
protected _networkRetry<T>(cb: () => Promise<Result<T, any>>, session?: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<T>;
|
|
56
57
|
protected _networkRetryException<T>(cb: () => Promise<T>, session?: InternalSession | null, requestType?: "client" | "server" | "admin"): Promise<T>;
|
|
@@ -128,7 +129,7 @@ declare class StackClientInterface {
|
|
|
128
129
|
accessToken: string;
|
|
129
130
|
refreshToken: string;
|
|
130
131
|
}, KnownErrors["EmailPasswordMismatch"]>>;
|
|
131
|
-
signUpWithCredential(email: string, password: string, emailVerificationRedirectUrl: string, session: InternalSession): Promise<Result<{
|
|
132
|
+
signUpWithCredential(email: string, password: string, emailVerificationRedirectUrl: string | undefined, session: InternalSession): Promise<Result<{
|
|
132
133
|
accessToken: string;
|
|
133
134
|
refreshToken: string;
|
|
134
135
|
}, KnownErrors["UserWithEmailAlreadyExists"] | KnownErrors["PasswordRequirementsNotMet"]>>;
|
|
@@ -56,6 +56,17 @@ var StackClientInterface = class {
|
|
|
56
56
|
return this.options.getBaseUrl() + "/api/v1";
|
|
57
57
|
}
|
|
58
58
|
async runNetworkDiagnostics(session, requestType) {
|
|
59
|
+
if (this.pendingNetworkDiagnostics) {
|
|
60
|
+
return await this.pendingNetworkDiagnostics;
|
|
61
|
+
}
|
|
62
|
+
this.pendingNetworkDiagnostics = this._runNetworkDiagnosticsInner(session, requestType);
|
|
63
|
+
try {
|
|
64
|
+
return await this.pendingNetworkDiagnostics;
|
|
65
|
+
} finally {
|
|
66
|
+
this.pendingNetworkDiagnostics = void 0;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async _runNetworkDiagnosticsInner(session, requestType) {
|
|
59
70
|
const tryRequest = async (cb) => {
|
|
60
71
|
try {
|
|
61
72
|
await cb();
|
|
@@ -70,12 +81,6 @@ var StackClientInterface = class {
|
|
|
70
81
|
throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
|
|
71
82
|
}
|
|
72
83
|
});
|
|
73
|
-
const apiRoot = session !== void 0 && requestType !== void 0 ? await tryRequest(async () => {
|
|
74
|
-
const res = await this.sendClientRequestInner("/", {}, session, requestType);
|
|
75
|
-
if (res.status === "error") {
|
|
76
|
-
throw res.error;
|
|
77
|
-
}
|
|
78
|
-
}) : "Not tested";
|
|
79
84
|
const baseUrlBackend = await tryRequest(async () => {
|
|
80
85
|
const res = await fetch(new URL("/health", this.getApiUrl()));
|
|
81
86
|
if (!res.ok) {
|
|
@@ -97,7 +102,6 @@ var StackClientInterface = class {
|
|
|
97
102
|
return {
|
|
98
103
|
"navigator?.onLine": import_globals.globalVar.navigator?.onLine,
|
|
99
104
|
cfTrace,
|
|
100
|
-
apiRoot,
|
|
101
105
|
baseUrlBackend,
|
|
102
106
|
prodDashboard,
|
|
103
107
|
prodBackend
|