You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

822 lines
19 KiB

  1. import { P as getDefaultExportFromCjs } from './dep-Bid9ssRr.js';
  2. import require$$0 from 'path';
  3. import { l as lib } from './dep-3RmXg9uo.js';
  4. import { createRequire as __cjs_createRequire } from 'node:module';
  5. const __require = __cjs_createRequire(import.meta.url);
  6. function _mergeNamespaces(n, m) {
  7. for (var i = 0; i < m.length; i++) {
  8. var e = m[i];
  9. if (typeof e !== 'string' && !Array.isArray(e)) { for (var k in e) {
  10. if (k !== 'default' && !(k in n)) {
  11. n[k] = e[k];
  12. }
  13. } }
  14. }
  15. return n;
  16. }
  17. var formatImportPrelude$2 = function formatImportPrelude(layer, media, supports) {
  18. const parts = [];
  19. if (typeof layer !== "undefined") {
  20. let layerParams = "layer";
  21. if (layer) {
  22. layerParams = `layer(${layer})`;
  23. }
  24. parts.push(layerParams);
  25. }
  26. if (typeof supports !== "undefined") {
  27. parts.push(`supports(${supports})`);
  28. }
  29. if (typeof media !== "undefined") {
  30. parts.push(media);
  31. }
  32. return parts.join(" ")
  33. };
  34. const formatImportPrelude$1 = formatImportPrelude$2;
  35. // Base64 encode an import with conditions
  36. // The order of conditions is important and is interleaved with cascade layer declarations
  37. // Each group of conditions and cascade layers needs to be interpreted in order
  38. // To achieve this we create a list of base64 encoded imports, where each import contains a stylesheet with another import.
  39. // Each import can define a single group of conditions and a single cascade layer.
  40. var base64EncodedImport = function base64EncodedConditionalImport(prelude, conditions) {
  41. conditions.reverse();
  42. const first = conditions.pop();
  43. let params = `${prelude} ${formatImportPrelude$1(
  44. first.layer,
  45. first.media,
  46. first.supports,
  47. )}`;
  48. for (const condition of conditions) {
  49. params = `'data:text/css;base64,${Buffer.from(`@import ${params}`).toString(
  50. "base64",
  51. )}' ${formatImportPrelude$1(
  52. condition.layer,
  53. condition.media,
  54. condition.supports,
  55. )}`;
  56. }
  57. return params
  58. };
  59. const base64EncodedConditionalImport = base64EncodedImport;
  60. var applyConditions$1 = function applyConditions(bundle, atRule) {
  61. bundle.forEach(stmt => {
  62. if (
  63. stmt.type === "charset" ||
  64. stmt.type === "warning" ||
  65. !stmt.conditions?.length
  66. ) {
  67. return
  68. }
  69. if (stmt.type === "import") {
  70. stmt.node.params = base64EncodedConditionalImport(
  71. stmt.fullUri,
  72. stmt.conditions,
  73. );
  74. return
  75. }
  76. const { nodes } = stmt;
  77. const { parent } = nodes[0];
  78. const atRules = [];
  79. // Convert conditions to at-rules
  80. for (const condition of stmt.conditions) {
  81. if (typeof condition.media !== "undefined") {
  82. const mediaNode = atRule({
  83. name: "media",
  84. params: condition.media,
  85. source: parent.source,
  86. });
  87. atRules.push(mediaNode);
  88. }
  89. if (typeof condition.supports !== "undefined") {
  90. const supportsNode = atRule({
  91. name: "supports",
  92. params: `(${condition.supports})`,
  93. source: parent.source,
  94. });
  95. atRules.push(supportsNode);
  96. }
  97. if (typeof condition.layer !== "undefined") {
  98. const layerNode = atRule({
  99. name: "layer",
  100. params: condition.layer,
  101. source: parent.source,
  102. });
  103. atRules.push(layerNode);
  104. }
  105. }
  106. // Add nodes to AST
  107. const outerAtRule = atRules.shift();
  108. const innerAtRule = atRules.reduce((previous, next) => {
  109. previous.append(next);
  110. return next
  111. }, outerAtRule);
  112. parent.insertBefore(nodes[0], outerAtRule);
  113. // remove nodes
  114. nodes.forEach(node => {
  115. node.parent = undefined;
  116. });
  117. // better output
  118. nodes[0].raws.before = nodes[0].raws.before || "\n";
  119. // wrap new rules with media query and/or layer at rule
  120. innerAtRule.append(nodes);
  121. stmt.type = "nodes";
  122. stmt.nodes = [outerAtRule];
  123. delete stmt.node;
  124. });
  125. };
  126. var applyRaws$1 = function applyRaws(bundle) {
  127. bundle.forEach((stmt, index) => {
  128. if (index === 0) return
  129. if (stmt.parent) {
  130. const { before } = stmt.parent.node.raws;
  131. if (stmt.type === "nodes") stmt.nodes[0].raws.before = before;
  132. else stmt.node.raws.before = before;
  133. } else if (stmt.type === "nodes") {
  134. stmt.nodes[0].raws.before = stmt.nodes[0].raws.before || "\n";
  135. }
  136. });
  137. };
  138. var applyStyles$1 = function applyStyles(bundle, styles) {
  139. styles.nodes = [];
  140. // Strip additional statements.
  141. bundle.forEach(stmt => {
  142. if (["charset", "import"].includes(stmt.type)) {
  143. stmt.node.parent = undefined;
  144. styles.append(stmt.node);
  145. } else if (stmt.type === "nodes") {
  146. stmt.nodes.forEach(node => {
  147. node.parent = undefined;
  148. styles.append(node);
  149. });
  150. }
  151. });
  152. };
  153. const anyDataURLRegexp = /^data:text\/css(?:;(base64|plain))?,/i;
  154. const base64DataURLRegexp = /^data:text\/css;base64,/i;
  155. const plainDataURLRegexp = /^data:text\/css;plain,/i;
  156. function isValid(url) {
  157. return anyDataURLRegexp.test(url)
  158. }
  159. function contents(url) {
  160. if (base64DataURLRegexp.test(url)) {
  161. // "data:text/css;base64,".length === 21
  162. return Buffer.from(url.slice(21), "base64").toString()
  163. }
  164. if (plainDataURLRegexp.test(url)) {
  165. // "data:text/css;plain,".length === 20
  166. return decodeURIComponent(url.slice(20))
  167. }
  168. // "data:text/css,".length === 14
  169. return decodeURIComponent(url.slice(14))
  170. }
  171. var dataUrl = {
  172. isValid,
  173. contents,
  174. };
  175. // external tooling
  176. const valueParser = lib;
  177. // extended tooling
  178. const { stringify } = valueParser;
  179. var parseStatements$1 = function parseStatements(result, styles, conditions, from) {
  180. const statements = [];
  181. let nodes = [];
  182. styles.each(node => {
  183. let stmt;
  184. if (node.type === "atrule") {
  185. if (node.name === "import")
  186. stmt = parseImport(result, node, conditions, from);
  187. else if (node.name === "charset")
  188. stmt = parseCharset(result, node, conditions, from);
  189. }
  190. if (stmt) {
  191. if (nodes.length) {
  192. statements.push({
  193. type: "nodes",
  194. nodes,
  195. conditions: [...conditions],
  196. from,
  197. });
  198. nodes = [];
  199. }
  200. statements.push(stmt);
  201. } else nodes.push(node);
  202. });
  203. if (nodes.length) {
  204. statements.push({
  205. type: "nodes",
  206. nodes,
  207. conditions: [...conditions],
  208. from,
  209. });
  210. }
  211. return statements
  212. };
  213. function parseCharset(result, atRule, conditions, from) {
  214. if (atRule.prev()) {
  215. return result.warn("@charset must precede all other statements", {
  216. node: atRule,
  217. })
  218. }
  219. return {
  220. type: "charset",
  221. node: atRule,
  222. conditions: [...conditions],
  223. from,
  224. }
  225. }
  226. function parseImport(result, atRule, conditions, from) {
  227. let prev = atRule.prev();
  228. // `@import` statements may follow other `@import` statements.
  229. if (prev) {
  230. do {
  231. if (
  232. prev.type === "comment" ||
  233. (prev.type === "atrule" && prev.name === "import")
  234. ) {
  235. prev = prev.prev();
  236. continue
  237. }
  238. break
  239. } while (prev)
  240. }
  241. // All `@import` statements may be preceded by `@charset` or `@layer` statements.
  242. // But the `@import` statements must be consecutive.
  243. if (prev) {
  244. do {
  245. if (
  246. prev.type === "comment" ||
  247. (prev.type === "atrule" &&
  248. (prev.name === "charset" || (prev.name === "layer" && !prev.nodes)))
  249. ) {
  250. prev = prev.prev();
  251. continue
  252. }
  253. return result.warn(
  254. "@import must precede all other statements (besides @charset or empty @layer)",
  255. { node: atRule },
  256. )
  257. } while (prev)
  258. }
  259. if (atRule.nodes) {
  260. return result.warn(
  261. "It looks like you didn't end your @import statement correctly. " +
  262. "Child nodes are attached to it.",
  263. { node: atRule },
  264. )
  265. }
  266. const params = valueParser(atRule.params).nodes;
  267. const stmt = {
  268. type: "import",
  269. uri: "",
  270. fullUri: "",
  271. node: atRule,
  272. conditions: [...conditions],
  273. from,
  274. };
  275. let layer;
  276. let media;
  277. let supports;
  278. for (let i = 0; i < params.length; i++) {
  279. const node = params[i];
  280. if (node.type === "space" || node.type === "comment") continue
  281. if (node.type === "string") {
  282. if (stmt.uri) {
  283. return result.warn(`Multiple url's in '${atRule.toString()}'`, {
  284. node: atRule,
  285. })
  286. }
  287. if (!node.value) {
  288. return result.warn(`Unable to find uri in '${atRule.toString()}'`, {
  289. node: atRule,
  290. })
  291. }
  292. stmt.uri = node.value;
  293. stmt.fullUri = stringify(node);
  294. continue
  295. }
  296. if (node.type === "function" && /^url$/i.test(node.value)) {
  297. if (stmt.uri) {
  298. return result.warn(`Multiple url's in '${atRule.toString()}'`, {
  299. node: atRule,
  300. })
  301. }
  302. if (!node.nodes?.[0]?.value) {
  303. return result.warn(`Unable to find uri in '${atRule.toString()}'`, {
  304. node: atRule,
  305. })
  306. }
  307. stmt.uri = node.nodes[0].value;
  308. stmt.fullUri = stringify(node);
  309. continue
  310. }
  311. if (!stmt.uri) {
  312. return result.warn(`Unable to find uri in '${atRule.toString()}'`, {
  313. node: atRule,
  314. })
  315. }
  316. if (
  317. (node.type === "word" || node.type === "function") &&
  318. /^layer$/i.test(node.value)
  319. ) {
  320. if (typeof layer !== "undefined") {
  321. return result.warn(`Multiple layers in '${atRule.toString()}'`, {
  322. node: atRule,
  323. })
  324. }
  325. if (typeof supports !== "undefined") {
  326. return result.warn(
  327. `layers must be defined before support conditions in '${atRule.toString()}'`,
  328. {
  329. node: atRule,
  330. },
  331. )
  332. }
  333. if (node.nodes) {
  334. layer = stringify(node.nodes);
  335. } else {
  336. layer = "";
  337. }
  338. continue
  339. }
  340. if (node.type === "function" && /^supports$/i.test(node.value)) {
  341. if (typeof supports !== "undefined") {
  342. return result.warn(
  343. `Multiple support conditions in '${atRule.toString()}'`,
  344. {
  345. node: atRule,
  346. },
  347. )
  348. }
  349. supports = stringify(node.nodes);
  350. continue
  351. }
  352. media = stringify(params.slice(i));
  353. break
  354. }
  355. if (!stmt.uri) {
  356. return result.warn(`Unable to find uri in '${atRule.toString()}'`, {
  357. node: atRule,
  358. })
  359. }
  360. if (
  361. typeof media !== "undefined" ||
  362. typeof layer !== "undefined" ||
  363. typeof supports !== "undefined"
  364. ) {
  365. stmt.conditions.push({
  366. layer,
  367. media,
  368. supports,
  369. });
  370. }
  371. return stmt
  372. }
  373. // builtin tooling
  374. const path$2 = require$$0;
  375. // placeholder tooling
  376. let sugarss;
  377. var processContent$1 = function processContent(
  378. result,
  379. content,
  380. filename,
  381. options,
  382. postcss,
  383. ) {
  384. const { plugins } = options;
  385. const ext = path$2.extname(filename);
  386. const parserList = [];
  387. // SugarSS support:
  388. if (ext === ".sss") {
  389. if (!sugarss) {
  390. /* c8 ignore next 3 */
  391. try {
  392. sugarss = __require('sugarss');
  393. } catch {} // Ignore
  394. }
  395. if (sugarss)
  396. return runPostcss(postcss, content, filename, plugins, [sugarss])
  397. }
  398. // Syntax support:
  399. if (result.opts.syntax?.parse) {
  400. parserList.push(result.opts.syntax.parse);
  401. }
  402. // Parser support:
  403. if (result.opts.parser) parserList.push(result.opts.parser);
  404. // Try the default as a last resort:
  405. parserList.push(null);
  406. return runPostcss(postcss, content, filename, plugins, parserList)
  407. };
  408. function runPostcss(postcss, content, filename, plugins, parsers, index) {
  409. if (!index) index = 0;
  410. return postcss(plugins)
  411. .process(content, {
  412. from: filename,
  413. parser: parsers[index],
  414. })
  415. .catch(err => {
  416. // If there's an error, try the next parser
  417. index++;
  418. // If there are no parsers left, throw it
  419. if (index === parsers.length) throw err
  420. return runPostcss(postcss, content, filename, plugins, parsers, index)
  421. })
  422. }
  423. const path$1 = require$$0;
  424. const dataURL = dataUrl;
  425. const parseStatements = parseStatements$1;
  426. const processContent = processContent$1;
  427. const resolveId$1 = (id) => id;
  428. const formatImportPrelude = formatImportPrelude$2;
  429. async function parseStyles$1(
  430. result,
  431. styles,
  432. options,
  433. state,
  434. conditions,
  435. from,
  436. postcss,
  437. ) {
  438. const statements = parseStatements(result, styles, conditions, from);
  439. for (const stmt of statements) {
  440. if (stmt.type !== "import" || !isProcessableURL(stmt.uri)) {
  441. continue
  442. }
  443. if (options.filter && !options.filter(stmt.uri)) {
  444. // rejected by filter
  445. continue
  446. }
  447. await resolveImportId(result, stmt, options, state, postcss);
  448. }
  449. let charset;
  450. const imports = [];
  451. const bundle = [];
  452. function handleCharset(stmt) {
  453. if (!charset) charset = stmt;
  454. // charsets aren't case-sensitive, so convert to lower case to compare
  455. else if (
  456. stmt.node.params.toLowerCase() !== charset.node.params.toLowerCase()
  457. ) {
  458. throw stmt.node.error(
  459. `Incompatible @charset statements:
  460. ${stmt.node.params} specified in ${stmt.node.source.input.file}
  461. ${charset.node.params} specified in ${charset.node.source.input.file}`,
  462. )
  463. }
  464. }
  465. // squash statements and their children
  466. statements.forEach(stmt => {
  467. if (stmt.type === "charset") handleCharset(stmt);
  468. else if (stmt.type === "import") {
  469. if (stmt.children) {
  470. stmt.children.forEach((child, index) => {
  471. if (child.type === "import") imports.push(child);
  472. else if (child.type === "charset") handleCharset(child);
  473. else bundle.push(child);
  474. // For better output
  475. if (index === 0) child.parent = stmt;
  476. });
  477. } else imports.push(stmt);
  478. } else if (stmt.type === "nodes") {
  479. bundle.push(stmt);
  480. }
  481. });
  482. return charset ? [charset, ...imports.concat(bundle)] : imports.concat(bundle)
  483. }
  484. async function resolveImportId(result, stmt, options, state, postcss) {
  485. if (dataURL.isValid(stmt.uri)) {
  486. // eslint-disable-next-line require-atomic-updates
  487. stmt.children = await loadImportContent(
  488. result,
  489. stmt,
  490. stmt.uri,
  491. options,
  492. state,
  493. postcss,
  494. );
  495. return
  496. } else if (dataURL.isValid(stmt.from.slice(-1))) {
  497. // Data urls can't be used as a base url to resolve imports.
  498. throw stmt.node.error(
  499. `Unable to import '${stmt.uri}' from a stylesheet that is embedded in a data url`,
  500. )
  501. }
  502. const atRule = stmt.node;
  503. let sourceFile;
  504. if (atRule.source?.input?.file) {
  505. sourceFile = atRule.source.input.file;
  506. }
  507. const base = sourceFile
  508. ? path$1.dirname(atRule.source.input.file)
  509. : options.root;
  510. const paths = [await options.resolve(stmt.uri, base, options, atRule)].flat();
  511. // Ensure that each path is absolute:
  512. const resolved = await Promise.all(
  513. paths.map(file => {
  514. return !path$1.isAbsolute(file)
  515. ? resolveId$1(file)
  516. : file
  517. }),
  518. );
  519. // Add dependency messages:
  520. resolved.forEach(file => {
  521. result.messages.push({
  522. type: "dependency",
  523. plugin: "postcss-import",
  524. file,
  525. parent: sourceFile,
  526. });
  527. });
  528. const importedContent = await Promise.all(
  529. resolved.map(file => {
  530. return loadImportContent(result, stmt, file, options, state, postcss)
  531. }),
  532. );
  533. // Merge loaded statements
  534. // eslint-disable-next-line require-atomic-updates
  535. stmt.children = importedContent.flat().filter(x => !!x);
  536. }
  537. async function loadImportContent(
  538. result,
  539. stmt,
  540. filename,
  541. options,
  542. state,
  543. postcss,
  544. ) {
  545. const atRule = stmt.node;
  546. const { conditions, from } = stmt;
  547. const stmtDuplicateCheckKey = conditions
  548. .map(condition =>
  549. formatImportPrelude(condition.layer, condition.media, condition.supports),
  550. )
  551. .join(":");
  552. if (options.skipDuplicates) {
  553. // skip files already imported at the same scope
  554. if (state.importedFiles[filename]?.[stmtDuplicateCheckKey]) {
  555. return
  556. }
  557. // save imported files to skip them next time
  558. if (!state.importedFiles[filename]) {
  559. state.importedFiles[filename] = {};
  560. }
  561. state.importedFiles[filename][stmtDuplicateCheckKey] = true;
  562. }
  563. if (from.includes(filename)) {
  564. return
  565. }
  566. const content = await options.load(filename, options);
  567. if (content.trim() === "" && options.warnOnEmpty) {
  568. result.warn(`${filename} is empty`, { node: atRule });
  569. return
  570. }
  571. // skip previous imported files not containing @import rules
  572. if (
  573. options.skipDuplicates &&
  574. state.hashFiles[content]?.[stmtDuplicateCheckKey]
  575. ) {
  576. return
  577. }
  578. const importedResult = await processContent(
  579. result,
  580. content,
  581. filename,
  582. options,
  583. postcss,
  584. );
  585. const styles = importedResult.root;
  586. result.messages = result.messages.concat(importedResult.messages);
  587. if (options.skipDuplicates) {
  588. const hasImport = styles.some(child => {
  589. return child.type === "atrule" && child.name === "import"
  590. });
  591. if (!hasImport) {
  592. // save hash files to skip them next time
  593. if (!state.hashFiles[content]) {
  594. state.hashFiles[content] = {};
  595. }
  596. state.hashFiles[content][stmtDuplicateCheckKey] = true;
  597. }
  598. }
  599. // recursion: import @import from imported file
  600. return parseStyles$1(
  601. result,
  602. styles,
  603. options,
  604. state,
  605. conditions,
  606. [...from, filename],
  607. postcss,
  608. )
  609. }
  610. function isProcessableURL(uri) {
  611. // skip protocol base uri (protocol://url) or protocol-relative
  612. if (/^(?:[a-z]+:)?\/\//i.test(uri)) {
  613. return false
  614. }
  615. // check for fragment or query
  616. try {
  617. // needs a base to parse properly
  618. const url = new URL(uri, "https://example.com");
  619. if (url.search) {
  620. return false
  621. }
  622. } catch {} // Ignore
  623. return true
  624. }
  625. var parseStyles_1 = parseStyles$1;
  626. // builtin tooling
  627. const path = require$$0;
  628. // internal tooling
  629. const applyConditions = applyConditions$1;
  630. const applyRaws = applyRaws$1;
  631. const applyStyles = applyStyles$1;
  632. const loadContent = () => "";
  633. const parseStyles = parseStyles_1;
  634. const resolveId = (id) => id;
  635. function AtImport(options) {
  636. options = {
  637. root: process.cwd(),
  638. path: [],
  639. skipDuplicates: true,
  640. resolve: resolveId,
  641. load: loadContent,
  642. plugins: [],
  643. addModulesDirectories: [],
  644. warnOnEmpty: true,
  645. ...options,
  646. };
  647. options.root = path.resolve(options.root);
  648. // convert string to an array of a single element
  649. if (typeof options.path === "string") options.path = [options.path];
  650. if (!Array.isArray(options.path)) options.path = [];
  651. options.path = options.path.map(p => path.resolve(options.root, p));
  652. return {
  653. postcssPlugin: "postcss-import",
  654. async Once(styles, { result, atRule, postcss }) {
  655. const state = {
  656. importedFiles: {},
  657. hashFiles: {},
  658. };
  659. if (styles.source?.input?.file) {
  660. state.importedFiles[styles.source.input.file] = {};
  661. }
  662. if (options.plugins && !Array.isArray(options.plugins)) {
  663. throw new Error("plugins option must be an array")
  664. }
  665. const bundle = await parseStyles(
  666. result,
  667. styles,
  668. options,
  669. state,
  670. [],
  671. [],
  672. postcss,
  673. );
  674. applyRaws(bundle);
  675. applyConditions(bundle, atRule);
  676. applyStyles(bundle, styles);
  677. },
  678. }
  679. }
  680. AtImport.postcss = true;
  681. var postcssImport = AtImport;
  682. var index = /*@__PURE__*/getDefaultExportFromCjs(postcssImport);
  683. var index$1 = /*#__PURE__*/_mergeNamespaces({
  684. __proto__: null,
  685. default: index
  686. }, [postcssImport]);
  687. export { index$1 as i };