@stackframe/stack-shared 2.8.31 → 2.8.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/config/schema.d.mts +104 -104
  3. package/dist/config/schema.d.ts +104 -104
  4. package/dist/config/schema.js +1 -1
  5. package/dist/config/schema.js.map +1 -1
  6. package/dist/esm/config/schema.js +1 -1
  7. package/dist/esm/config/schema.js.map +1 -1
  8. package/dist/esm/helpers/production-mode.js +2 -1
  9. package/dist/esm/helpers/production-mode.js.map +1 -1
  10. package/dist/esm/interface/admin-interface.js +16 -19
  11. package/dist/esm/interface/admin-interface.js.map +1 -1
  12. package/dist/esm/interface/client-interface.js +36 -8
  13. package/dist/esm/interface/client-interface.js.map +1 -1
  14. package/dist/esm/interface/crud/items.js +22 -0
  15. package/dist/esm/interface/crud/items.js.map +1 -0
  16. package/dist/esm/interface/crud/users.js +1 -1
  17. package/dist/esm/interface/crud/users.js.map +1 -1
  18. package/dist/esm/interface/server-interface.js +21 -0
  19. package/dist/esm/interface/server-interface.js.map +1 -1
  20. package/dist/esm/known-errors.js +14 -5
  21. package/dist/esm/known-errors.js.map +1 -1
  22. package/dist/esm/schema-fields.js +31 -1
  23. package/dist/esm/schema-fields.js.map +1 -1
  24. package/dist/esm/utils/jwt.js +42 -37
  25. package/dist/esm/utils/jwt.js.map +1 -1
  26. package/dist/esm/utils/types.js.map +1 -1
  27. package/dist/esm/utils/urls.js +54 -0
  28. package/dist/esm/utils/urls.js.map +1 -1
  29. package/dist/helpers/password.d.mts +3 -0
  30. package/dist/helpers/password.d.ts +3 -0
  31. package/dist/helpers/production-mode.js +2 -1
  32. package/dist/helpers/production-mode.js.map +1 -1
  33. package/dist/index.d.mts +4 -0
  34. package/dist/index.d.ts +4 -0
  35. package/dist/interface/admin-interface.d.mts +5 -9
  36. package/dist/interface/admin-interface.d.ts +5 -9
  37. package/dist/interface/admin-interface.js +16 -19
  38. package/dist/interface/admin-interface.js.map +1 -1
  39. package/dist/interface/client-interface.d.mts +14 -8
  40. package/dist/interface/client-interface.d.ts +14 -8
  41. package/dist/interface/client-interface.js +36 -8
  42. package/dist/interface/client-interface.js.map +1 -1
  43. package/dist/interface/crud/items.d.mts +30 -0
  44. package/dist/interface/crud/items.d.ts +30 -0
  45. package/dist/interface/crud/items.js +47 -0
  46. package/dist/interface/crud/items.js.map +1 -0
  47. package/dist/interface/crud/project-api-keys.d.mts +4 -4
  48. package/dist/interface/crud/project-api-keys.d.ts +4 -4
  49. package/dist/interface/crud/projects.d.mts +7 -7
  50. package/dist/interface/crud/projects.d.ts +7 -7
  51. package/dist/interface/crud/users.js +1 -1
  52. package/dist/interface/crud/users.js.map +1 -1
  53. package/dist/interface/server-interface.d.mts +6 -0
  54. package/dist/interface/server-interface.d.ts +6 -0
  55. package/dist/interface/server-interface.js +21 -0
  56. package/dist/interface/server-interface.js.map +1 -1
  57. package/dist/known-errors.d.mts +4 -1
  58. package/dist/known-errors.d.ts +4 -1
  59. package/dist/known-errors.js +14 -5
  60. package/dist/known-errors.js.map +1 -1
  61. package/dist/schema-fields.d.mts +6 -2
  62. package/dist/schema-fields.d.ts +6 -2
  63. package/dist/schema-fields.js +31 -0
  64. package/dist/schema-fields.js.map +1 -1
  65. package/dist/utils/jwt.d.mts +11 -11
  66. package/dist/utils/jwt.d.ts +11 -11
  67. package/dist/utils/jwt.js +44 -42
  68. package/dist/utils/jwt.js.map +1 -1
  69. package/dist/utils/types.d.mts +11 -1
  70. package/dist/utils/types.d.ts +11 -1
  71. package/dist/utils/types.js.map +1 -1
  72. package/dist/utils/urls.d.mts +3 -1
  73. package/dist/utils/urls.d.ts +3 -1
  74. package/dist/utils/urls.js +56 -0
  75. package/dist/utils/urls.js.map +1 -1
  76. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/jwt.tsx"],"sourcesContent":["import crypto from \"crypto\";\nimport elliptic from \"elliptic\";\nimport * as jose from \"jose\";\nimport { JOSEError } from \"jose/errors\";\nimport { encodeBase64Url } from \"./bytes\";\nimport { StackAssertionError } from \"./errors\";\nimport { globalVar } from \"./globals\";\nimport { pick } from \"./objects\";\n\nconst STACK_SERVER_SECRET = process.env.STACK_SERVER_SECRET ?? \"\";\ntry {\n jose.base64url.decode(STACK_SERVER_SECRET);\n} catch (e) {\n throw new Error(\"STACK_SERVER_SECRET is not valid. Please use the generateKeys script to generate a new secret.\");\n}\n\n// TODO: remove this after moving everyone to project specific JWTs\nexport async function legacySignGlobalJWT(issuer: string, payload: any, expirationTime = \"5m\") {\n const privateJwk = await jose.importJWK(await getPrivateJwk(STACK_SERVER_SECRET));\n return await new jose.SignJWT(payload)\n .setProtectedHeader({ alg: \"ES256\" })\n .setIssuer(issuer)\n .setIssuedAt()\n .setExpirationTime(expirationTime)\n .sign(privateJwk);\n}\n\n// TODO: remove this after moving everyone to project specific JWTs\nexport async function legacyVerifyGlobalJWT(issuer: string, jwt: string) {\n const jwkSet = jose.createLocalJWKSet(await getPublicJwkSet(STACK_SERVER_SECRET));\n const verified = await jose.jwtVerify(jwt, jwkSet, { issuer });\n return verified.payload;\n}\n\nexport async function signJWT(options: {\n issuer: string,\n audience: string,\n payload: any,\n expirationTime?: string,\n}) {\n const secret = getPerAudienceSecret({ audience: options.audience, secret: STACK_SERVER_SECRET });\n const kid = getKid({ secret });\n const privateJwk = await jose.importJWK(await getPrivateJwk(secret));\n return await new jose.SignJWT(options.payload)\n .setProtectedHeader({ alg: \"ES256\", kid })\n .setIssuer(options.issuer)\n .setIssuedAt()\n .setAudience(options.audience)\n .setExpirationTime(options.expirationTime || \"5m\")\n .sign(privateJwk);\n}\n\nexport async function verifyJWT(options: {\n issuer: string,\n jwt: string,\n}) {\n const audience = jose.decodeJwt(options.jwt).aud;\n if (!audience || typeof audience !== \"string\") {\n throw new JOSEError(\"Invalid JWT audience\");\n }\n const secret = getPerAudienceSecret({ audience, secret: STACK_SERVER_SECRET });\n const jwkSet = jose.createLocalJWKSet(await getPublicJwkSet(secret));\n const verified = await jose.jwtVerify(options.jwt, jwkSet, { issuer: options.issuer });\n return verified.payload;\n}\n\nexport type PrivateJwk = {\n kty: \"EC\",\n alg: \"ES256\",\n crv: \"P-256\",\n kid: string,\n d: string,\n x: string,\n y: string,\n};\nexport async function getPrivateJwk(secret: string): Promise<PrivateJwk> {\n const secretHash = await globalVar.crypto.subtle.digest(\"SHA-256\", jose.base64url.decode(secret));\n const priv = new Uint8Array(secretHash);\n\n const ec = new elliptic.ec('p256');\n const key = ec.keyFromPrivate(priv);\n const publicKey = key.getPublic();\n\n return {\n kty: 'EC',\n crv: 'P-256',\n alg: 'ES256',\n kid: getKid({ secret }),\n d: encodeBase64Url(priv),\n x: encodeBase64Url(publicKey.getX().toBuffer()),\n y: encodeBase64Url(publicKey.getY().toBuffer()),\n };\n}\n\nexport type PublicJwk = {\n kty: \"EC\",\n alg: \"ES256\",\n crv: \"P-256\",\n kid: string,\n x: string,\n y: string,\n};\nexport async function getPublicJwkSet(secretOrPrivateJwk: string | PrivateJwk): Promise<{ keys: PublicJwk[] }> {\n const privateJwk = typeof secretOrPrivateJwk === \"string\" ? await getPrivateJwk(secretOrPrivateJwk) : secretOrPrivateJwk;\n const jwk = pick(privateJwk, [\"kty\", \"alg\", \"crv\", \"x\", \"y\", \"kid\"]);\n return {\n keys: [jwk],\n };\n}\n\nexport function getPerAudienceSecret(options: {\n audience: string,\n secret: string,\n}) {\n if (options.audience === \"kid\") {\n throw new StackAssertionError(\"You cannot use the 'kid' audience for a per-audience secret, see comment below in jwt.tsx\");\n }\n return jose.base64url.encode(\n crypto\n .createHash('sha256')\n // TODO we should prefix a string like \"stack-audience-secret\" before we hash so you can't use `getKid(...)` to get the secret for eg. the \"kid\" audience if the same secret value is used\n // Sadly doing this modification is a bit annoying as we need to leave the old keys to be valid for a little longer\n .update(JSON.stringify([options.secret, options.audience]))\n .digest()\n );\n};\n\nexport function getKid(options: {\n secret: string,\n}) {\n return jose.base64url.encode(\n crypto\n .createHash('sha256')\n .update(JSON.stringify([options.secret, \"kid\"])) // TODO see above in getPerAudienceSecret\n .digest()\n ).slice(0, 12);\n}\n"],"mappings":"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","names":["import_errors","elliptic","crypto","crypto"]}
1
+ {"version":3,"sources":["../../src/utils/jwt.tsx"],"sourcesContent":["import crypto from \"crypto\";\nimport elliptic from \"elliptic\";\nimport * as jose from \"jose\";\nimport { JOSEError } from \"jose/errors\";\nimport { encodeBase64Url } from \"./bytes\";\nimport { getEnvVariable } from \"./env\";\nimport { StackAssertionError } from \"./errors\";\nimport { globalVar } from \"./globals\";\nimport { pick } from \"./objects\";\n\nfunction getStackServerSecret() {\n const STACK_SERVER_SECRET = getEnvVariable(\"STACK_SERVER_SECRET\");\n try {\n jose.base64url.decode(STACK_SERVER_SECRET);\n } catch (e) {\n throw new StackAssertionError(\"STACK_SERVER_SECRET is not valid. Please use the generateKeys script to generate a new secret.\", { cause: e });\n }\n return STACK_SERVER_SECRET;\n}\n\nexport async function signJWT(options: {\n issuer: string,\n audience: string,\n payload: any,\n expirationTime?: string,\n}) {\n const privateJwks = await getPrivateJwks({ audience: options.audience });\n const privateKey = await jose.importJWK(privateJwks[0]);\n\n return await new jose.SignJWT(options.payload)\n .setProtectedHeader({ alg: \"ES256\", kid: privateJwks[0].kid })\n .setIssuer(options.issuer)\n .setIssuedAt()\n .setAudience(options.audience)\n .setExpirationTime(options.expirationTime || \"5m\")\n .sign(privateKey);\n}\n\nexport async function verifyJWT(options: {\n allowedIssuers: string[],\n jwt: string,\n}) {\n const decodedJwt = jose.decodeJwt(options.jwt);\n const audience = decodedJwt.aud;\n if (!audience || typeof audience !== \"string\") {\n throw new JOSEError(\"Invalid JWT audience\");\n }\n\n const jwkSet = jose.createLocalJWKSet(await getPublicJwkSet(await getPrivateJwks({ audience })));\n const verified = await jose.jwtVerify(options.jwt, jwkSet, { issuer: options.allowedIssuers });\n return verified.payload;\n}\n\nexport type PrivateJwk = {\n kty: \"EC\",\n alg: \"ES256\",\n crv: \"P-256\",\n kid: string,\n d: string,\n x: string,\n y: string,\n};\nasync function getPrivateJwkFromDerivedSecret(derivedSecret: string, kid: string): Promise<PrivateJwk> {\n const secretHash = await globalVar.crypto.subtle.digest(\"SHA-256\", jose.base64url.decode(derivedSecret));\n const priv = new Uint8Array(secretHash);\n\n const ec = new elliptic.ec('p256');\n const key = ec.keyFromPrivate(priv);\n const publicKey = key.getPublic();\n\n return {\n kty: 'EC',\n crv: 'P-256',\n alg: 'ES256',\n kid: kid,\n d: encodeBase64Url(priv),\n x: encodeBase64Url(publicKey.getX().toBuffer()),\n y: encodeBase64Url(publicKey.getY().toBuffer()),\n };\n}\n\n/**\n * Returns a list of valid private JWKs for the given audience, with the first one taking precedence when signing new\n * JWTs.\n */\nexport async function getPrivateJwks(options: {\n audience: string,\n}): Promise<PrivateJwk[]> {\n const getHashOfJwkInfo = (type: string) => jose.base64url.encode(\n crypto\n .createHash('sha256')\n .update(JSON.stringify([type, getStackServerSecret(), {\n audience: options.audience,\n }]))\n .digest()\n );\n const perAudienceSecret = getHashOfJwkInfo(\"stack-jwk-audience-secret\");\n const perAudienceKid = getHashOfJwkInfo(\"stack-jwk-kid\").slice(0, 12);\n\n const oldPerAudienceSecret = oldGetPerAudienceSecret({ audience: options.audience });\n const oldPerAudienceKid = oldGetKid({ secret: oldPerAudienceSecret });\n\n return [\n // TODO next-release: make this not take precedence; then, in the release after that, remove it entirely\n await getPrivateJwkFromDerivedSecret(oldPerAudienceSecret, oldPerAudienceKid),\n\n await getPrivateJwkFromDerivedSecret(perAudienceSecret, perAudienceKid),\n ];\n}\n\nexport type PublicJwk = {\n kty: \"EC\",\n alg: \"ES256\",\n crv: \"P-256\",\n kid: string,\n x: string,\n y: string,\n};\nexport async function getPublicJwkSet(privateJwks: PrivateJwk[]): Promise<{ keys: PublicJwk[] }> {\n return {\n keys: privateJwks.map(jwk => pick(jwk, [\"kty\", \"alg\", \"crv\", \"x\", \"y\", \"kid\"])),\n };\n}\n\nfunction oldGetPerAudienceSecret(options: {\n audience: string,\n}) {\n if (options.audience === \"kid\") {\n throw new StackAssertionError(\"You cannot use the 'kid' audience for a per-audience secret, see comment below in jwt.tsx\");\n }\n return jose.base64url.encode(\n crypto\n .createHash('sha256')\n // TODO we should prefix a string like \"stack-audience-secret\" before we hash so you can't use `getKid(...)` to get the secret for eg. the \"kid\" audience if the same secret value is used\n // Sadly doing this modification is a bit annoying as we need to leave the old keys to be valid for a little longer\n .update(JSON.stringify([getStackServerSecret(), options.audience]))\n .digest()\n );\n};\n\nexport function oldGetKid(options: {\n secret: string,\n}) {\n return jose.base64url.encode(\n crypto\n .createHash('sha256')\n .update(JSON.stringify([options.secret, \"kid\"])) // TODO see above in getPerAudienceSecret\n .digest()\n ).slice(0, 12);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAmB;AACnB,sBAAqB;AACrB,WAAsB;AACtB,oBAA0B;AAC1B,mBAAgC;AAChC,iBAA+B;AAC/B,IAAAA,iBAAoC;AACpC,qBAA0B;AAC1B,qBAAqB;AAErB,SAAS,uBAAuB;AAC9B,QAAM,0BAAsB,2BAAe,qBAAqB;AAChE,MAAI;AACF,IAAK,eAAU,OAAO,mBAAmB;AAAA,EAC3C,SAAS,GAAG;AACV,UAAM,IAAI,mCAAoB,kGAAkG,EAAE,OAAO,EAAE,CAAC;AAAA,EAC9I;AACA,SAAO;AACT;AAEA,eAAsB,QAAQ,SAK3B;AACD,QAAM,cAAc,MAAM,eAAe,EAAE,UAAU,QAAQ,SAAS,CAAC;AACvE,QAAM,aAAa,MAAW,eAAU,YAAY,CAAC,CAAC;AAEtD,SAAO,MAAM,IAAS,aAAQ,QAAQ,OAAO,EAC1C,mBAAmB,EAAE,KAAK,SAAS,KAAK,YAAY,CAAC,EAAE,IAAI,CAAC,EAC5D,UAAU,QAAQ,MAAM,EACxB,YAAY,EACZ,YAAY,QAAQ,QAAQ,EAC5B,kBAAkB,QAAQ,kBAAkB,IAAI,EAChD,KAAK,UAAU;AACpB;AAEA,eAAsB,UAAU,SAG7B;AACD,QAAM,aAAkB,eAAU,QAAQ,GAAG;AAC7C,QAAM,WAAW,WAAW;AAC5B,MAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,UAAM,IAAI,wBAAU,sBAAsB;AAAA,EAC5C;AAEA,QAAM,SAAc,uBAAkB,MAAM,gBAAgB,MAAM,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC;AAC/F,QAAM,WAAW,MAAW,eAAU,QAAQ,KAAK,QAAQ,EAAE,QAAQ,QAAQ,eAAe,CAAC;AAC7F,SAAO,SAAS;AAClB;AAWA,eAAe,+BAA+B,eAAuB,KAAkC;AACrG,QAAM,aAAa,MAAM,yBAAU,OAAO,OAAO,OAAO,WAAgB,eAAU,OAAO,aAAa,CAAC;AACvG,QAAM,OAAO,IAAI,WAAW,UAAU;AAEtC,QAAM,KAAK,IAAI,gBAAAC,QAAS,GAAG,MAAM;AACjC,QAAM,MAAM,GAAG,eAAe,IAAI;AAClC,QAAM,YAAY,IAAI,UAAU;AAEhC,SAAO;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AAAA,IACA,OAAG,8BAAgB,IAAI;AAAA,IACvB,OAAG,8BAAgB,UAAU,KAAK,EAAE,SAAS,CAAC;AAAA,IAC9C,OAAG,8BAAgB,UAAU,KAAK,EAAE,SAAS,CAAC;AAAA,EAChD;AACF;AAMA,eAAsB,eAAe,SAEX;AACxB,QAAM,mBAAmB,CAAC,SAAsB,eAAU;AAAA,IACxD,cAAAC,QACG,WAAW,QAAQ,EACnB,OAAO,KAAK,UAAU,CAAC,MAAM,qBAAqB,GAAG;AAAA,MACpD,UAAU,QAAQ;AAAA,IACpB,CAAC,CAAC,CAAC,EACF,OAAO;AAAA,EACZ;AACA,QAAM,oBAAoB,iBAAiB,2BAA2B;AACtE,QAAM,iBAAiB,iBAAiB,eAAe,EAAE,MAAM,GAAG,EAAE;AAEpE,QAAM,uBAAuB,wBAAwB,EAAE,UAAU,QAAQ,SAAS,CAAC;AACnF,QAAM,oBAAoB,UAAU,EAAE,QAAQ,qBAAqB,CAAC;AAEpE,SAAO;AAAA;AAAA,IAEL,MAAM,+BAA+B,sBAAsB,iBAAiB;AAAA,IAE5E,MAAM,+BAA+B,mBAAmB,cAAc;AAAA,EACxE;AACF;AAUA,eAAsB,gBAAgB,aAA2D;AAC/F,SAAO;AAAA,IACL,MAAM,YAAY,IAAI,aAAO,qBAAK,KAAK,CAAC,OAAO,OAAO,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC;AAAA,EAChF;AACF;AAEA,SAAS,wBAAwB,SAE9B;AACD,MAAI,QAAQ,aAAa,OAAO;AAC9B,UAAM,IAAI,mCAAoB,2FAA2F;AAAA,EAC3H;AACA,SAAY,eAAU;AAAA,IACpB,cAAAA,QACG,WAAW,QAAQ,EAGnB,OAAO,KAAK,UAAU,CAAC,qBAAqB,GAAG,QAAQ,QAAQ,CAAC,CAAC,EACjE,OAAO;AAAA,EACZ;AACF;AAEO,SAAS,UAAU,SAEvB;AACD,SAAY,eAAU;AAAA,IACpB,cAAAC,QACG,WAAW,QAAQ,EACnB,OAAO,KAAK,UAAU,CAAC,QAAQ,QAAQ,KAAK,CAAC,CAAC,EAC9C,OAAO;AAAA,EACZ,EAAE,MAAM,GAAG,EAAE;AACf;","names":["import_errors","elliptic","crypto","crypto"]}
@@ -33,6 +33,16 @@ type OptionalKeys<T> = {
33
33
  type RequiredKeys<T> = {
34
34
  [K in keyof T]: {} extends Pick<T, K> ? never : K;
35
35
  }[keyof T];
36
+ /**
37
+ * Returns a type whose keys are the intersection of the keys of T and U, deeply.
38
+ */
39
+ type KeyIntersect<T, U> = {
40
+ [K in keyof T & keyof U]?: T[K] & U[K];
41
+ } | {
42
+ [K in RequiredKeys<T> & keyof U]: T[K] & U[K];
43
+ } | {
44
+ [K in RequiredKeys<U> & keyof T]: U[K] & T[K];
45
+ };
36
46
  /**
37
47
  * Returns ALL keys of all union elements.
38
48
  */
@@ -92,4 +102,4 @@ declare function typeAssertExtends<T, S>(): ([
92
102
  ] extends [S] ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to extend ${TypeToString<S>}`>);
93
103
  declare function typeAssertIs<T, U>(): (IsAny<T> extends true ? (IsAny<U> extends true ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>) : IsAny<U> extends true ? TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`> : [T] extends [U] ? ([U] extends [T] ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>);
94
104
 
95
- export { type AllUnionKeys, type AntiIntersect, type CollapseObjectUnion, type DeepRemoveOptionalUndefined, type Expand, type IfAndOnlyIf, type IntersectAll, type IsAny, type IsNever, type IsNullish, type IsUnion, type LastUnionElement, type NullishCoalesce, type OptionalKeys, type PrettifyType, type PseudoAntiIntersect, type RequiredKeys, type SubtractType, type TypeToString, type UnionToIntersection, type UnionToTuple, typeAssert, typeAssertExtends, typeAssertIs };
105
+ export { type AllUnionKeys, type AntiIntersect, type CollapseObjectUnion, type DeepRemoveOptionalUndefined, type Expand, type IfAndOnlyIf, type IntersectAll, type IsAny, type IsNever, type IsNullish, type IsUnion, type KeyIntersect, type LastUnionElement, type NullishCoalesce, type OptionalKeys, type PrettifyType, type PseudoAntiIntersect, type RequiredKeys, type SubtractType, type TypeToString, type UnionToIntersection, type UnionToTuple, typeAssert, typeAssertExtends, typeAssertIs };
@@ -33,6 +33,16 @@ type OptionalKeys<T> = {
33
33
  type RequiredKeys<T> = {
34
34
  [K in keyof T]: {} extends Pick<T, K> ? never : K;
35
35
  }[keyof T];
36
+ /**
37
+ * Returns a type whose keys are the intersection of the keys of T and U, deeply.
38
+ */
39
+ type KeyIntersect<T, U> = {
40
+ [K in keyof T & keyof U]?: T[K] & U[K];
41
+ } | {
42
+ [K in RequiredKeys<T> & keyof U]: T[K] & U[K];
43
+ } | {
44
+ [K in RequiredKeys<U> & keyof T]: U[K] & T[K];
45
+ };
36
46
  /**
37
47
  * Returns ALL keys of all union elements.
38
48
  */
@@ -92,4 +102,4 @@ declare function typeAssertExtends<T, S>(): ([
92
102
  ] extends [S] ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to extend ${TypeToString<S>}`>);
93
103
  declare function typeAssertIs<T, U>(): (IsAny<T> extends true ? (IsAny<U> extends true ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>) : IsAny<U> extends true ? TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`> : [T] extends [U] ? ([U] extends [T] ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>);
94
104
 
95
- export { type AllUnionKeys, type AntiIntersect, type CollapseObjectUnion, type DeepRemoveOptionalUndefined, type Expand, type IfAndOnlyIf, type IntersectAll, type IsAny, type IsNever, type IsNullish, type IsUnion, type LastUnionElement, type NullishCoalesce, type OptionalKeys, type PrettifyType, type PseudoAntiIntersect, type RequiredKeys, type SubtractType, type TypeToString, type UnionToIntersection, type UnionToTuple, typeAssert, typeAssertExtends, typeAssertIs };
105
+ export { type AllUnionKeys, type AntiIntersect, type CollapseObjectUnion, type DeepRemoveOptionalUndefined, type Expand, type IfAndOnlyIf, type IntersectAll, type IsAny, type IsNever, type IsNullish, type IsUnion, type KeyIntersect, type LastUnionElement, type NullishCoalesce, type OptionalKeys, type PrettifyType, type PseudoAntiIntersect, type RequiredKeys, type SubtractType, type TypeToString, type UnionToIntersection, type UnionToTuple, typeAssert, typeAssertExtends, typeAssertIs };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/types.tsx"],"sourcesContent":["import { DeepPartial } from \"./objects\";\nimport { Join } from \"./strings\";\n\nexport type IsAny<T> = 0 extends (1 & T) ? true : false;\nexport type IsNever<T> = [T] extends [never] ? true : false;\nexport type IsNullish<T> = [T] extends [null | undefined] ? true : false;\nexport type IsUnion<T, U = T> =\n IsNever<T> extends true ? false\n : IsAny<T> extends true ? false\n : T extends U // distributive conditional https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types\n ? /* if the *whole* original type (`U`) still fits inside the current variant, then `T` wasn’t a union */ ([U] extends [T] ? false : true)\n : never;\n\nexport type NullishCoalesce<T, U> = T extends null | undefined ? U : T;\n\nexport type LastUnionElement<U> = UnionToIntersection<U extends any ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L & U : never;\n\n/**\n * Makes a type prettier by recursively expanding all object types. For example, `Omit<{ a: 1 }, \"a\">` becomes just `{}`.\n */\nexport type Expand<T> = T extends (...args: infer A) => infer R\n ? (\n ((...args: A) => R) extends T\n ? (...args: Expand<A>) => Expand<R>\n : ((...args: Expand<A>) => Expand<R>) & { [K in keyof T]: Expand<T[K]> }\n )\n : (\n T extends object\n ? { [K in keyof T]: Expand<T[K]> }\n : T\n );\n\n\n/**\n * Removes all optional undefined/never keys from an object.\n */\nexport type DeepRemoveOptionalUndefined<T> = T extends object ? { [K in keyof T]: DeepRemoveOptionalUndefined<T[K]> } : T;\n\n// why this works: https://stackoverflow.com/a/50375286\nexport type UnionToIntersection<U> =\n (U extends any ? (x: U) => void : never) extends ((x: infer I) => void) ? I : never\n\ntype _UnionToTupleInner<U, R extends any[], Last> = UnionToTuple<Exclude<U, Last>, [...R, Last]>\nexport type UnionToTuple<U, R extends any[] = []> = [U] extends [never] ? R : _UnionToTupleInner<U, R, LastUnionElement<U>>;\n\nexport type CollapseObjectUnion<T extends object> = {\n [K in AllUnionKeys<T>]?: T extends Record<K, infer V> ? V : never;\n};\ntypeAssertIs<CollapseObjectUnion<{ a: string } | { b: number }>, { a?: string, b?: number }>()();\ntypeAssertIs<CollapseObjectUnion<{ a: string } | { a: number }>, { a?: string | number }>()();\n\nexport type IntersectAll<T extends any[]> = UnionToIntersection<T[number]>;\n\nexport type OptionalKeys<T> = {\n [K in keyof T]: {} extends Pick<T, K> ? K : never;\n}[keyof T];\nexport type RequiredKeys<T> = {\n [K in keyof T]: {} extends Pick<T, K> ? never : K;\n}[keyof T];\n\n/**\n * Returns ALL keys of all union elements.\n */\nexport type AllUnionKeys<T extends object> = T extends T ? keyof T : never;\ntypeAssertIs<AllUnionKeys<{ a: string } | { b: number }>, \"a\" | \"b\">()();\n\nexport type SubtractType<T, U> = T extends object ? { [K in keyof T]: K extends keyof U ? SubtractType<T[K], U[K]> : T[K] } : (T extends U ? never : T); // note: this only works due to the distributive property of conditional types https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types\n\n\ntype _AntiIntersectInner<T, U> = T extends object ? (\n & Omit<U, keyof T>\n & { [K in keyof Pick<U, { [K in keyof T & keyof U]: U[K] extends T[K] ? (T[K] extends U[K] ? never : K) : never }[keyof T & keyof U]>]: PseudoAntiIntersect<T[K], U[K]> }\n & { [K in keyof Pick<U, keyof T & keyof U>]?: PseudoAntiIntersect<T[K], U[K]> }\n) : U;\n/**\n * Returns a type R such that T & R = U.\n */\nexport type AntiIntersect<T, U> = U extends T ? _AntiIntersectInner<T, U> : \"Cannot anti-intersect a type with a type that is not a subtype of it\"; // NOTE: This type is mostly untested — not sure how well it works on the edge cases\nexport type PseudoAntiIntersect<T, U> = _AntiIntersectInner<T, T & U>;\n\n/**\n * A variation of TypeScript's conditionals with slightly different semantics. It is the perfect type for cases where:\n *\n * - If all possible values are contained in `Extends`, then it will be mapped to `Then`.\n * - If all possible values are not contained in `Extends`, then it will be mapped to `Otherwise`.\n * - If some possible values are contained in `Extends` and some are not, then it will be mapped to `Then | Otherwise`.\n *\n * This is different from TypeScript's built-in conditional types (`Value extends Extends ? Then : Otherwise`), which\n * returns `Otherwise` for the third case (causing unsoundness in many real-world cases).\n */\nexport type IfAndOnlyIf<Value, Extends, Then, Otherwise> =\n | (Value extends Extends ? never : Otherwise)\n | (Value & Extends extends never ? never : Then);\n\n\n/**\n * Can be used to prettify a type in the IDE; for example, some complicated intersected types can be flattened into a single type.\n */\nexport type PrettifyType<T> = T extends object ? { [K in keyof T]: T[K] } & {} : T;\n\ntype _ToStringAndJoin<T extends any[], Separator extends string> =\n T extends [infer U, ...infer Rest extends any[]]\n ? `${TypeToString<U>}${Rest extends [any, ...any[]] ? `${Separator}${_ToStringAndJoin<Rest, Separator>}` : \"\"}`\n : \"<error-joining-tuple-elements>\";\ntype _TypeToStringInner<T> =\n IsAny<T> extends true ? \"any\"\n : IsNever<T> extends true ? \"never\"\n : IsUnion<T> extends true ? _ToStringAndJoin<UnionToTuple<T>, \" | \">\n : [T] extends [number] ? (number extends T ? \"number\" : `${T}`)\n : [T] extends [boolean] ? `${T}`\n : [T] extends [undefined] ? \"undefined\"\n : [T] extends [null] ? \"null\"\n : [T] extends [string] ? (string extends T ? \"string\" : `'${T}'`)\n : [T] extends [[]] ? \"[]\"\n : [T] extends [[any, ...any[]]] ? `[${_ToStringAndJoin<T, \", \">}]`\n : [T] extends [(infer E)[]] ? `${TypeToString<E>}[]`\n : [T] extends [Function] ? \"function\"\n : [T] extends [symbol] ? `symbol(${T['description']})`\n : [T] extends [object] ? `{ ${Join<UnionToTuple<{ [K in keyof T]: `${TypeToString<K>}: ${TypeToString<T[K]>}` }[keyof T]>, \", \">} }`\n : \"<unknown-type>\"\nexport type TypeToString<T> = _TypeToStringInner<T> extends `${infer S}` ? S : never;\n\n/**\n * Can be used to create assertions on types. For example, if passed any T other than `true`, the following will\n * show a type error:\n *\n * ```ts\n * typeAssert<T>()(); // the second pair of braces is important!\n * ```\n */\nexport function typeAssert<T>(): (\n IsAny<T> extends true ? TypeAssertionError<`Type assertion failed. Expected true, but got any.`>\n : IsNever<T> extends true ? TypeAssertionError<`Type assertion failed. Expected true, but got never.`>\n : T extends true ? (() => undefined)\n : TypeAssertionError<`Type assertion failed. Expected true, but got: ${TypeToString<T>}`>\n) {\n return (() => undefined) as any;\n}\ntype TypeAssertionError<T> =\n & [T]\n & /* this promise makes sure that if we accidentally forget the second pair of braces, eslint will complain (if we have no-floating-promises enabled) */ Promise<any>;\n\n\ntypeAssertExtends<ReturnType<typeof typeAssert<true>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssert<false>>, TypeAssertionError<`Type assertion failed. Expected true, but got: false`>>()();\ntypeAssertExtends<ReturnType<typeof typeAssert<never>>, TypeAssertionError<`Type assertion failed. Expected true, but got never.`>>()();\ntypeAssertExtends<ReturnType<typeof typeAssert<any>>, TypeAssertionError<`Type assertion failed. Expected true, but got any.`>>()();\n\n/**\n * Functionally equivalent to `typeAssert<T extends S ? true : false>()()`, but with better error messages.\n */\nexport function typeAssertExtends<T, S>(): (\n [T] extends [S] ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to extend ${TypeToString<S>}`>\n) {\n return (() => undefined) as any;\n}\n\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<never, true>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<any, true>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<false, false>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<\"abc\", string>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<{a: 1, b: 123}, {a: number}>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<never, never>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<true, any>>, () => undefined>()();\n\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<{a: number}, {a: 1}>>, [\"Type assertion failed. Expected { 'a': number } to extend { 'a': 1 }\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<any, never>>, [\"Type assertion failed. Expected any to extend never\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<false, true>>, [\"Type assertion failed. Expected false to extend true\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<false, never>>, [\"Type assertion failed. Expected false to extend never\"]>()();\n\n\nexport function typeAssertIs<T, U>(): (\n IsAny<T> extends true ? (IsAny<U> extends true ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>)\n : IsAny<U> extends true ? TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>\n : [T] extends [U] ? ([U] extends [T] ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>)\n : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>\n) {\n return (() => undefined) as any;\n}\n\ntypeAssertExtends<ReturnType<typeof typeAssertIs<\"123\", \"123\">>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<{a: 1}, {a: 1}>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<DeepPartial<{a: 1}>, {a?: 1}>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<any, any>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<never, never>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<1, any>>, [\"Type assertion failed. Expected 1 to be any\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<any, 1>>, [\"Type assertion failed. Expected any to be 1\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<false, true>>, [\"Type assertion failed. Expected false to be true\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<{a: number}, {a: 1}>>, [\"Type assertion failed. Expected { 'a': number } to be { 'a': 1 }\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<any, never>>, [\"Type assertion failed. Expected any to be never\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<false, true>>, [\"Type assertion failed. Expected false to be true\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<false, never>>, [\"Type assertion failed. Expected false to be never\"]>()();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgDA,aAA6F,EAAE;AAC/F,aAA0F,EAAE;AAe5F,aAAqE,EAAE;AAkEhE,SAAS,aAKd;AACA,SAAQ,MAAM;AAChB;AAMA,kBAAwE,EAAE;AAC1E,kBAAoI,EAAE;AACtI,kBAAoI,EAAE;AACtI,kBAAgI,EAAE;AAK3H,SAAS,oBAEd;AACA,SAAQ,MAAM;AAChB;AAEA,kBAAsF,EAAE;AACxF,kBAAoF,EAAE;AACtF,kBAAuF,EAAE;AACzF,kBAAwF,EAAE;AAC1F,kBAAsG,EAAE;AACxG,kBAAuF,EAAE;AACzF,kBAAoF,EAAE;AAEtF,kBAAuJ,EAAE;AACzJ,kBAA6H,EAAE;AAC/H,kBAA+H,EAAE;AACjI,kBAAiI,EAAE;AAG5H,SAAS,eAKd;AACA,SAAQ,MAAM;AAChB;AAEA,kBAAkF,EAAE;AACpF,kBAAoF,EAAE;AACtF,kBAAkG,EAAE;AACpG,kBAA8E,EAAE;AAChF,kBAAkF,EAAE;AACpF,kBAA4G,EAAE;AAC9G,kBAA4G,EAAE;AAC9G,kBAAsH,EAAE;AACxH,kBAA8I,EAAE;AAChJ,kBAAoH,EAAE;AACtH,kBAAsH,EAAE;AACxH,kBAAwH,EAAE;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/types.tsx"],"sourcesContent":["import { DeepPartial } from \"./objects\";\nimport { Join } from \"./strings\";\n\nexport type IsAny<T> = 0 extends (1 & T) ? true : false;\nexport type IsNever<T> = [T] extends [never] ? true : false;\nexport type IsNullish<T> = [T] extends [null | undefined] ? true : false;\nexport type IsUnion<T, U = T> =\n IsNever<T> extends true ? false\n : IsAny<T> extends true ? false\n : T extends U // distributive conditional https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types\n ? /* if the *whole* original type (`U`) still fits inside the current variant, then `T` wasn’t a union */ ([U] extends [T] ? false : true)\n : never;\n\nexport type NullishCoalesce<T, U> = T extends null | undefined ? U : T;\n\nexport type LastUnionElement<U> = UnionToIntersection<U extends any ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L & U : never;\n\n/**\n * Makes a type prettier by recursively expanding all object types. For example, `Omit<{ a: 1 }, \"a\">` becomes just `{}`.\n */\nexport type Expand<T> = T extends (...args: infer A) => infer R\n ? (\n ((...args: A) => R) extends T\n ? (...args: Expand<A>) => Expand<R>\n : ((...args: Expand<A>) => Expand<R>) & { [K in keyof T]: Expand<T[K]> }\n )\n : (\n T extends object\n ? { [K in keyof T]: Expand<T[K]> }\n : T\n );\n\n\n/**\n * Removes all optional undefined/never keys from an object.\n */\nexport type DeepRemoveOptionalUndefined<T> = T extends object ? { [K in keyof T]: DeepRemoveOptionalUndefined<T[K]> } : T;\n\n// why this works: https://stackoverflow.com/a/50375286\nexport type UnionToIntersection<U> =\n (U extends any ? (x: U) => void : never) extends ((x: infer I) => void) ? I : never\n\ntype _UnionToTupleInner<U, R extends any[], Last> = UnionToTuple<Exclude<U, Last>, [...R, Last]>\nexport type UnionToTuple<U, R extends any[] = []> = [U] extends [never] ? R : _UnionToTupleInner<U, R, LastUnionElement<U>>;\n\nexport type CollapseObjectUnion<T extends object> = {\n [K in AllUnionKeys<T>]?: T extends Record<K, infer V> ? V : never;\n};\ntypeAssertIs<CollapseObjectUnion<{ a: string } | { b: number }>, { a?: string, b?: number }>()();\ntypeAssertIs<CollapseObjectUnion<{ a: string } | { a: number }>, { a?: string | number }>()();\n\nexport type IntersectAll<T extends any[]> = UnionToIntersection<T[number]>;\n\nexport type OptionalKeys<T> = {\n [K in keyof T]: {} extends Pick<T, K> ? K : never;\n}[keyof T];\nexport type RequiredKeys<T> = {\n [K in keyof T]: {} extends Pick<T, K> ? never : K;\n}[keyof T];\n\n/**\n * Returns a type whose keys are the intersection of the keys of T and U, deeply.\n */\nexport type KeyIntersect<T, U> =\n | { [K in keyof T & keyof U]?: T[K] & U[K] }\n | { [K in RequiredKeys<T> & keyof U]: T[K] & U[K] }\n | { [K in RequiredKeys<U> & keyof T]: U[K] & T[K] }\n\n/**\n * Returns ALL keys of all union elements.\n */\nexport type AllUnionKeys<T extends object> = T extends T ? keyof T : never;\ntypeAssertIs<AllUnionKeys<{ a: string } | { b: number }>, \"a\" | \"b\">()();\n\nexport type SubtractType<T, U> = T extends object ? { [K in keyof T]: K extends keyof U ? SubtractType<T[K], U[K]> : T[K] } : (T extends U ? never : T); // note: this only works due to the distributive property of conditional types https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types\n\n\ntype _AntiIntersectInner<T, U> = T extends object ? (\n & Omit<U, keyof T>\n & { [K in keyof Pick<U, { [K in keyof T & keyof U]: U[K] extends T[K] ? (T[K] extends U[K] ? never : K) : never }[keyof T & keyof U]>]: PseudoAntiIntersect<T[K], U[K]> }\n & { [K in keyof Pick<U, keyof T & keyof U>]?: PseudoAntiIntersect<T[K], U[K]> }\n) : U;\n/**\n * Returns a type R such that T & R = U.\n */\nexport type AntiIntersect<T, U> = U extends T ? _AntiIntersectInner<T, U> : \"Cannot anti-intersect a type with a type that is not a subtype of it\"; // NOTE: This type is mostly untested — not sure how well it works on the edge cases\nexport type PseudoAntiIntersect<T, U> = _AntiIntersectInner<T, T & U>;\n\n/**\n * A variation of TypeScript's conditionals with slightly different semantics. It is the perfect type for cases where:\n *\n * - If all possible values are contained in `Extends`, then it will be mapped to `Then`.\n * - If all possible values are not contained in `Extends`, then it will be mapped to `Otherwise`.\n * - If some possible values are contained in `Extends` and some are not, then it will be mapped to `Then | Otherwise`.\n *\n * This is different from TypeScript's built-in conditional types (`Value extends Extends ? Then : Otherwise`), which\n * returns `Otherwise` for the third case (causing unsoundness in many real-world cases).\n */\nexport type IfAndOnlyIf<Value, Extends, Then, Otherwise> =\n | (Value extends Extends ? never : Otherwise)\n | (Value & Extends extends never ? never : Then);\n\n\n/**\n * Can be used to prettify a type in the IDE; for example, some complicated intersected types can be flattened into a single type.\n */\nexport type PrettifyType<T> = T extends object ? { [K in keyof T]: T[K] } & {} : T;\n\ntype _ToStringAndJoin<T extends any[], Separator extends string> =\n T extends [infer U, ...infer Rest extends any[]]\n ? `${TypeToString<U>}${Rest extends [any, ...any[]] ? `${Separator}${_ToStringAndJoin<Rest, Separator>}` : \"\"}`\n : \"<error-joining-tuple-elements>\";\ntype _TypeToStringInner<T> =\n IsAny<T> extends true ? \"any\"\n : IsNever<T> extends true ? \"never\"\n : IsUnion<T> extends true ? _ToStringAndJoin<UnionToTuple<T>, \" | \">\n : [T] extends [number] ? (number extends T ? \"number\" : `${T}`)\n : [T] extends [boolean] ? `${T}`\n : [T] extends [undefined] ? \"undefined\"\n : [T] extends [null] ? \"null\"\n : [T] extends [string] ? (string extends T ? \"string\" : `'${T}'`)\n : [T] extends [[]] ? \"[]\"\n : [T] extends [[any, ...any[]]] ? `[${_ToStringAndJoin<T, \", \">}]`\n : [T] extends [(infer E)[]] ? `${TypeToString<E>}[]`\n : [T] extends [Function] ? \"function\"\n : [T] extends [symbol] ? `symbol(${T['description']})`\n : [T] extends [object] ? `{ ${Join<UnionToTuple<{ [K in keyof T]: `${TypeToString<K>}: ${TypeToString<T[K]>}` }[keyof T]>, \", \">} }`\n : \"<unknown-type>\"\nexport type TypeToString<T> = _TypeToStringInner<T> extends `${infer S}` ? S : never;\n\n/**\n * Can be used to create assertions on types. For example, if passed any T other than `true`, the following will\n * show a type error:\n *\n * ```ts\n * typeAssert<T>()(); // the second pair of braces is important!\n * ```\n */\nexport function typeAssert<T>(): (\n IsAny<T> extends true ? TypeAssertionError<`Type assertion failed. Expected true, but got any.`>\n : IsNever<T> extends true ? TypeAssertionError<`Type assertion failed. Expected true, but got never.`>\n : T extends true ? (() => undefined)\n : TypeAssertionError<`Type assertion failed. Expected true, but got: ${TypeToString<T>}`>\n) {\n return (() => undefined) as any;\n}\ntype TypeAssertionError<T> =\n & [T]\n & /* this promise makes sure that if we accidentally forget the second pair of braces, eslint will complain (if we have no-floating-promises enabled) */ Promise<any>;\n\n\ntypeAssertExtends<ReturnType<typeof typeAssert<true>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssert<false>>, TypeAssertionError<`Type assertion failed. Expected true, but got: false`>>()();\ntypeAssertExtends<ReturnType<typeof typeAssert<never>>, TypeAssertionError<`Type assertion failed. Expected true, but got never.`>>()();\ntypeAssertExtends<ReturnType<typeof typeAssert<any>>, TypeAssertionError<`Type assertion failed. Expected true, but got any.`>>()();\n\n/**\n * Functionally equivalent to `typeAssert<T extends S ? true : false>()()`, but with better error messages.\n */\nexport function typeAssertExtends<T, S>(): (\n [T] extends [S] ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to extend ${TypeToString<S>}`>\n) {\n return (() => undefined) as any;\n}\n\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<never, true>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<any, true>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<false, false>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<\"abc\", string>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<{a: 1, b: 123}, {a: number}>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<never, never>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<true, any>>, () => undefined>()();\n\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<{a: number}, {a: 1}>>, [\"Type assertion failed. Expected { 'a': number } to extend { 'a': 1 }\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<any, never>>, [\"Type assertion failed. Expected any to extend never\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<false, true>>, [\"Type assertion failed. Expected false to extend true\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertExtends<false, never>>, [\"Type assertion failed. Expected false to extend never\"]>()();\n\n\nexport function typeAssertIs<T, U>(): (\n IsAny<T> extends true ? (IsAny<U> extends true ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>)\n : IsAny<U> extends true ? TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>\n : [T] extends [U] ? ([U] extends [T] ? (() => undefined) : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>)\n : TypeAssertionError<`Type assertion failed. Expected ${TypeToString<T>} to be ${TypeToString<U>}`>\n) {\n return (() => undefined) as any;\n}\n\ntypeAssertExtends<ReturnType<typeof typeAssertIs<\"123\", \"123\">>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<{a: 1}, {a: 1}>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<DeepPartial<{a: 1}>, {a?: 1}>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<any, any>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<never, never>>, () => undefined>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<1, any>>, [\"Type assertion failed. Expected 1 to be any\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<any, 1>>, [\"Type assertion failed. Expected any to be 1\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<false, true>>, [\"Type assertion failed. Expected false to be true\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<{a: number}, {a: 1}>>, [\"Type assertion failed. Expected { 'a': number } to be { 'a': 1 }\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<any, never>>, [\"Type assertion failed. Expected any to be never\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<false, true>>, [\"Type assertion failed. Expected false to be true\"]>()();\ntypeAssertExtends<ReturnType<typeof typeAssertIs<false, never>>, [\"Type assertion failed. Expected false to be never\"]>()();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgDA,aAA6F,EAAE;AAC/F,aAA0F,EAAE;AAuB5F,aAAqE,EAAE;AAkEhE,SAAS,aAKd;AACA,SAAQ,MAAM;AAChB;AAMA,kBAAwE,EAAE;AAC1E,kBAAoI,EAAE;AACtI,kBAAoI,EAAE;AACtI,kBAAgI,EAAE;AAK3H,SAAS,oBAEd;AACA,SAAQ,MAAM;AAChB;AAEA,kBAAsF,EAAE;AACxF,kBAAoF,EAAE;AACtF,kBAAuF,EAAE;AACzF,kBAAwF,EAAE;AAC1F,kBAAsG,EAAE;AACxG,kBAAuF,EAAE;AACzF,kBAAoF,EAAE;AAEtF,kBAAuJ,EAAE;AACzJ,kBAA6H,EAAE;AAC/H,kBAA+H,EAAE;AACjI,kBAAiI,EAAE;AAG5H,SAAS,eAKd;AACA,SAAQ,MAAM;AAChB;AAEA,kBAAkF,EAAE;AACpF,kBAAoF,EAAE;AACtF,kBAAkG,EAAE;AACpG,kBAA8E,EAAE;AAChF,kBAAkF,EAAE;AACpF,kBAA4G,EAAE;AAC9G,kBAA4G,EAAE;AAC9G,kBAAsH,EAAE;AACxH,kBAA8I,EAAE;AAChJ,kBAAoH,EAAE;AACtH,kBAAsH,EAAE;AACxH,kBAAwH,EAAE;","names":[]}
@@ -1,6 +1,8 @@
1
1
  declare function createUrlIfValid(...args: ConstructorParameters<typeof URL>): URL | null;
2
2
  declare function isValidUrl(url: string): boolean;
3
3
  declare function isValidHostname(hostname: string): boolean;
4
+ declare function isValidHostnameWithWildcards(hostname: string): boolean;
5
+ declare function matchHostnamePattern(pattern: string, hostname: string): boolean;
4
6
  declare function isLocalhost(urlOrString: string | URL): boolean;
5
7
  declare function isRelative(url: string): boolean;
6
8
  declare function getRelativePart(url: URL): string;
@@ -17,4 +19,4 @@ declare function url(strings: TemplateStringsArray | readonly string[], ...value
17
19
  */
18
20
  declare function urlString(strings: TemplateStringsArray | readonly string[], ...values: (string | number | boolean)[]): string;
19
21
 
20
- export { createUrlIfValid, getRelativePart, isLocalhost, isRelative, isValidHostname, isValidUrl, url, urlString };
22
+ export { createUrlIfValid, getRelativePart, isLocalhost, isRelative, isValidHostname, isValidHostnameWithWildcards, isValidUrl, matchHostnamePattern, url, urlString };
@@ -1,6 +1,8 @@
1
1
  declare function createUrlIfValid(...args: ConstructorParameters<typeof URL>): URL | null;
2
2
  declare function isValidUrl(url: string): boolean;
3
3
  declare function isValidHostname(hostname: string): boolean;
4
+ declare function isValidHostnameWithWildcards(hostname: string): boolean;
5
+ declare function matchHostnamePattern(pattern: string, hostname: string): boolean;
4
6
  declare function isLocalhost(urlOrString: string | URL): boolean;
5
7
  declare function isRelative(url: string): boolean;
6
8
  declare function getRelativePart(url: URL): string;
@@ -17,4 +19,4 @@ declare function url(strings: TemplateStringsArray | readonly string[], ...value
17
19
  */
18
20
  declare function urlString(strings: TemplateStringsArray | readonly string[], ...values: (string | number | boolean)[]): string;
19
21
 
20
- export { createUrlIfValid, getRelativePart, isLocalhost, isRelative, isValidHostname, isValidUrl, url, urlString };
22
+ export { createUrlIfValid, getRelativePart, isLocalhost, isRelative, isValidHostname, isValidHostnameWithWildcards, isValidUrl, matchHostnamePattern, url, urlString };
@@ -25,7 +25,9 @@ __export(urls_exports, {
25
25
  isLocalhost: () => isLocalhost,
26
26
  isRelative: () => isRelative,
27
27
  isValidHostname: () => isValidHostname,
28
+ isValidHostnameWithWildcards: () => isValidHostnameWithWildcards,
28
29
  isValidUrl: () => isValidUrl,
30
+ matchHostnamePattern: () => matchHostnamePattern,
29
31
  url: () => url,
30
32
  urlString: () => urlString
31
33
  });
@@ -43,10 +45,62 @@ function isValidUrl(url2) {
43
45
  return !!createUrlIfValid(url2);
44
46
  }
45
47
  function isValidHostname(hostname) {
48
+ if (!hostname || hostname.startsWith(".") || hostname.endsWith(".") || hostname.includes("..")) {
49
+ return false;
50
+ }
46
51
  const url2 = createUrlIfValid(`https://${hostname}`);
47
52
  if (!url2) return false;
48
53
  return url2.hostname === hostname;
49
54
  }
55
+ function isValidHostnameWithWildcards(hostname) {
56
+ if (!hostname) return false;
57
+ const hasWildcard = hostname.includes("*");
58
+ if (!hasWildcard) {
59
+ return isValidHostname(hostname);
60
+ }
61
+ if (hostname.startsWith(".") || hostname.endsWith(".")) {
62
+ return false;
63
+ }
64
+ if (hostname.includes("..")) {
65
+ return false;
66
+ }
67
+ const testHostname = hostname.replace(/\*+/g, "wildcard");
68
+ if (!/^[a-zA-Z0-9.-]+$/.test(testHostname)) {
69
+ return false;
70
+ }
71
+ const segments = hostname.split(/\*+/);
72
+ for (let i = 0; i < segments.length; i++) {
73
+ const segment = segments[i];
74
+ if (segment === "") continue;
75
+ if (i === 0 && segment.startsWith(".")) {
76
+ return false;
77
+ }
78
+ if (i === segments.length - 1 && segment.endsWith(".")) {
79
+ return false;
80
+ }
81
+ if (segment.includes("..")) {
82
+ return false;
83
+ }
84
+ }
85
+ return true;
86
+ }
87
+ function matchHostnamePattern(pattern, hostname) {
88
+ if (!pattern.includes("*")) {
89
+ return pattern === hostname;
90
+ }
91
+ let regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
92
+ const doubleWildcardPlaceholder = "\0DOUBLE_WILDCARD\0";
93
+ regexPattern = regexPattern.replace(/\*\*/g, doubleWildcardPlaceholder);
94
+ regexPattern = regexPattern.replace(/\*/g, "[^.]*");
95
+ regexPattern = regexPattern.replace(new RegExp(doubleWildcardPlaceholder, "g"), ".*");
96
+ regexPattern = "^" + regexPattern + "$";
97
+ try {
98
+ const regex = new RegExp(regexPattern);
99
+ return regex.test(hostname);
100
+ } catch {
101
+ return false;
102
+ }
103
+ }
50
104
  function isLocalhost(urlOrString) {
51
105
  const url2 = createUrlIfValid(urlOrString);
52
106
  if (!url2) return false;
@@ -78,7 +132,9 @@ function urlString(strings, ...values) {
78
132
  isLocalhost,
79
133
  isRelative,
80
134
  isValidHostname,
135
+ isValidHostnameWithWildcards,
81
136
  isValidUrl,
137
+ matchHostnamePattern,
82
138
  url,
83
139
  urlString
84
140
  });
@@ -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 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 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\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA2C;AAC3C,qBAAiC;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;AAChD,QAAMA,OAAM,iBAAiB,WAAW,QAAQ,EAAE;AAClD,MAAI,CAACA,KAAK,QAAO;AACjB,SAAOA,KAAI,aAAa;AAC1B;AAeO,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,OAAG,0CAA2B,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,aAAO,iCAAiB,SAAS,GAAG,OAAO,IAAI,kBAAkB,CAAC;AACpE;","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\n\n"],"mappings":"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","names":["url"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.8.31",
3
+ "version": "2.8.34",
4
4
  "files": [
5
5
  "README.md",
6
6
  "dist",