{"version":3,"sources":["meteor://💻app/packages/routepolicy/main.js","meteor://💻app/packages/routepolicy/routepolicy.js"],"names":["module","export","RoutePolicy","RoutePolicyConstructor","link","default","v","constructor","urlPrefixTypes","urlPrefixMatches","urlPrefix","url","startsWith","checkType","type","includes","checkUrlPrefix","existingType","checkForConflictWithStatic","_testManifest","policy","check","manifest","conflict","find","resource","where","WebApp","require","errorMessage","Object","keys","clientPrograms","some","arch","declare","problem","Error","isValidUrl","classify","prefix","urlPrefixesFor","entries","filter","_prefix","_type","map","sort"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAAA,MAAM,CAACC,MAAP,CAAc;AAACC,aAAW,EAAC,MAAIA;AAAjB,CAAd;AAA6C,IAAIC,sBAAJ;AAA2BH,MAAM,CAACI,IAAP,CAAY,eAAZ,EAA4B;AAACC,SAAO,CAACC,CAAD,EAAG;AAACH,0BAAsB,GAACG,CAAvB;AAAyB;;AAArC,CAA5B,EAAmE,CAAnE;AACjE,MAAMJ,WAAW,GAAG,IAAIC,sBAAJ,EAApB,C;;;;;;;;;;;ACDPH,MAAM,CAACC,MAAP,CAAc;AAACI,SAAO,EAAC,MAAIH;AAAb,CAAd;;AAsBe,MAAMA,WAAN,CAAkB;AAC/BK,aAAW,GAAG;AACZ;AACA,SAAKC,cAAL,GAAsB,EAAtB;AACD;;AAEDC,kBAAgB,CAACC,SAAD,EAAYC,GAAZ,EAAiB;AAC/B,WAAOA,GAAG,CAACC,UAAJ,CAAeF,SAAf,CAAP;AACD;;AAEDG,WAAS,CAACC,IAAD,EAAO;AACd,QAAI,CAAC,CAAC,SAAD,EAAY,eAAZ,EAA6BC,QAA7B,CAAsCD,IAAtC,CAAL,EAAkD;AAChD,aAAO,qDAAP;AACD;;AACD,WAAO,IAAP;AACD;;AAEDE,gBAAc,CAACN,SAAD,EAAYI,IAAZ,EAAkB;AAC9B,QAAI,CAACJ,SAAS,CAACE,UAAV,CAAqB,GAArB,CAAL,EAAgC;AAC9B,aAAO,4CAAP;AACD;;AAED,QAAIF,SAAS,KAAK,GAAlB,EAAuB;AACrB,aAAO,gCAAP;AACD;;AAED,UAAMO,YAAY,GAAG,KAAKT,cAAL,CAAoBE,SAApB,CAArB;;AACA,QAAIO,YAAY,IAAIA,YAAY,KAAKH,IAArC,EAA2C;AACzC,aAAO,+BAAwBJ,SAAxB,2DACYO,YADZ,CAAP;AAED;;AAED,WAAO,IAAP;AACD;;AAEDC,4BAA0B,CAACR,SAAD,EAAYI,IAAZ,EAAkBK,aAAlB,EAAiC;AACzD,QAAIL,IAAI,KAAK,eAAb,EAA8B;AAC5B,aAAO,IAAP;AACD;;AAED,UAAMM,MAAM,GAAG,IAAf;;AAEA,aAASC,KAAT,CAAeC,QAAf,EAAyB;AACvB,YAAMC,QAAQ,GAAGD,QAAQ,CAACE,IAAT,CAAcC,QAAQ,IACrCA,QAAQ,CAACX,IAAT,KAAkB,QAAlB,IACAW,QAAQ,CAACC,KAAT,KAAmB,QADnB,IAEAN,MAAM,CAACX,gBAAP,CAAwBC,SAAxB,EAAmCe,QAAQ,CAACd,GAA5C,CAHe,CAAjB;;AAMA,UAAIY,QAAJ,EAAc;AACZ,eAAO,0BAAmBA,QAAQ,CAACZ,GAA5B,6BAAkDG,IAAlD,yBACIJ,SADJ,CAAP;AAED;;AAED,aAAO,IAAP;AACD;;AAAA;;AAED,QAAIS,aAAJ,EAAmB;AACjB,aAAOE,KAAK,CAACF,aAAD,CAAZ;AACD;;AAED,UAAM;AAAEQ;AAAF,QAAaC,OAAO,CAAC,eAAD,CAA1B;;AACA,QAAIC,YAAY,GAAG,IAAnB;AAEAC,UAAM,CAACC,IAAP,CAAYJ,MAAM,CAACK,cAAnB,EAAmCC,IAAnC,CAAwCC,IAAI,IAAI;AAC9C,YAAM;AAAEZ;AAAF,UAAeK,MAAM,CAACK,cAAP,CAAsBE,IAAtB,CAArB;AACA,aAAOL,YAAY,GAAGR,KAAK,CAACC,QAAD,CAA3B;AACD,KAHD;AAKA,WAAOO,YAAP;AACD;;AAEDM,SAAO,CAACzB,SAAD,EAAYI,IAAZ,EAAkB;AACvB,UAAMsB,OAAO,GACX,KAAKvB,SAAL,CAAeC,IAAf,KACA,KAAKE,cAAL,CAAoBN,SAApB,EAA+BI,IAA/B,CADA,IAEA,KAAKI,0BAAL,CAAgCR,SAAhC,EAA2CI,IAA3C,CAHF;;AAIA,QAAIsB,OAAJ,EAAa;AACX,YAAM,IAAIC,KAAJ,CAAUD,OAAV,CAAN;AACD,KAPsB,CAQvB;;;AACA,SAAK5B,cAAL,CAAoBE,SAApB,IAAiCI,IAAjC;AACD;;AAEDwB,YAAU,CAAC3B,GAAD,EAAM;AACd,WAAOA,GAAG,CAACC,UAAJ,CAAe,GAAf,CAAP;AACD;;AAED2B,UAAQ,CAAC5B,GAAD,EAAM;AACZ,QAAI,CAAC,KAAK2B,UAAL,CAAgB3B,GAAhB,CAAL,EAA2B;AACzB,YAAM,IAAI0B,KAAJ,uCAAyC1B,GAAzC,EAAN;AACD;;AAED,UAAM6B,MAAM,GAAGV,MAAM,CAACC,IAAP,CAAY,KAAKvB,cAAjB,EAAiCgB,IAAjC,CAAsCgB,MAAM,IACzD,KAAK/B,gBAAL,CAAsB+B,MAAtB,EAA8B7B,GAA9B,CADa,CAAf;AAIA,WAAO6B,MAAM,GAAG,KAAKhC,cAAL,CAAoBgC,MAApB,CAAH,GAAiC,IAA9C;AACD;;AAEDC,gBAAc,CAAC3B,IAAD,EAAO;AACnB,WAAOgB,MAAM,CAACY,OAAP,CAAe,KAAKlC,cAApB,EACJmC,MADI,CACG;AAAA,UAAC,CAACC,OAAD,EAAUC,KAAV,CAAD;AAAA,aAAsBA,KAAK,KAAK/B,IAAhC;AAAA,KADH,EAEJgC,GAFI,CAEA;AAAA,UAAC,CAACF,OAAD,CAAD;AAAA,aAAeA,OAAf;AAAA,KAFA,EAGJG,IAHI,EAAP;AAID;;AAzG8B,C","file":"/packages/routepolicy.js","sourcesContent":["import { default as RoutePolicyConstructor } from './routepolicy';\nexport const RoutePolicy = new RoutePolicyConstructor();\n","// In addition to listing specific files to be cached, the browser\n// application cache manifest allows URLs to be designated as NETWORK\n// (always fetched from the Internet) and FALLBACK (which we use to\n// serve app HTML on arbitrary URLs).\n//\n// The limitation of the manifest file format is that the designations\n// are by prefix only: if \"/foo\" is declared NETWORK then \"/foobar\"\n// will also be treated as a network route.\n//\n// RoutePolicy is a low-level API for declaring the route type of URL prefixes:\n//\n// \"network\": for network routes that should not conflict with static\n// resources. (For example, if \"/sockjs/\" is a network route, we\n// shouldn't have \"/sockjs/red-sock.jpg\" as a static resource).\n//\n// \"static-online\": for static resources which should not be cached in\n// the app cache. This is implemented by also adding them to the\n// NETWORK section (as otherwise the browser would receive app HTML\n// for them because of the FALLBACK section), but static-online routes\n// don't need to be checked for conflict with static resources.\n\n\nexport default class RoutePolicy {\n constructor() {\n // maps prefix to a type\n this.urlPrefixTypes = {};\n }\n\n urlPrefixMatches(urlPrefix, url) {\n return url.startsWith(urlPrefix);\n }\n\n checkType(type) {\n if (!['network', 'static-online'].includes(type)) {\n return 'the route type must be \"network\" or \"static-online\"';\n }\n return null;\n }\n\n checkUrlPrefix(urlPrefix, type) {\n if (!urlPrefix.startsWith('/')) {\n return 'a route URL prefix must begin with a slash';\n }\n\n if (urlPrefix === '/') {\n return 'a route URL prefix cannot be /';\n }\n\n const existingType = this.urlPrefixTypes[urlPrefix];\n if (existingType && existingType !== type) {\n return `the route URL prefix ${urlPrefix} has already been declared ` +\n `to be of type ${existingType}`;\n }\n\n return null;\n }\n\n checkForConflictWithStatic(urlPrefix, type, _testManifest) {\n if (type === 'static-online') {\n return null;\n }\n\n const policy = this;\n\n function check(manifest) {\n const conflict = manifest.find(resource => (\n resource.type === 'static' &&\n resource.where === 'client' &&\n policy.urlPrefixMatches(urlPrefix, resource.url)\n ));\n\n if (conflict) {\n return `static resource ${conflict.url} conflicts with ${type} ` +\n `route ${urlPrefix}`;\n }\n\n return null;\n };\n\n if (_testManifest) {\n return check(_testManifest);\n }\n\n const { WebApp } = require(\"meteor/webapp\");\n let errorMessage = null;\n\n Object.keys(WebApp.clientPrograms).some(arch => {\n const { manifest } = WebApp.clientPrograms[arch];\n return errorMessage = check(manifest);\n });\n\n return errorMessage;\n }\n\n declare(urlPrefix, type) {\n const problem =\n this.checkType(type) ||\n this.checkUrlPrefix(urlPrefix, type) ||\n this.checkForConflictWithStatic(urlPrefix, type);\n if (problem) {\n throw new Error(problem);\n }\n // TODO overlapping prefixes, e.g. /foo/ and /foo/bar/\n this.urlPrefixTypes[urlPrefix] = type;\n }\n\n isValidUrl(url) {\n return url.startsWith('/');\n }\n\n classify(url) {\n if (!this.isValidUrl(url)) {\n throw new Error(`url must be a relative URL: ${url}`);\n }\n\n const prefix = Object.keys(this.urlPrefixTypes).find(prefix =>\n this.urlPrefixMatches(prefix, url)\n );\n\n return prefix ? this.urlPrefixTypes[prefix] : null;\n }\n\n urlPrefixesFor(type) {\n return Object.entries(this.urlPrefixTypes)\n .filter(([_prefix, _type]) => _type === type)\n .map(([_prefix]) => _prefix)\n .sort();\n }\n}\n"]}