@fastkit/plugboy-sass-plugin 3.0.0 → 3.0.2

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.
@@ -1,7 +1,6 @@
1
1
  import { Plugin } from "@fastkit/plugboy";
2
2
  import sass from "rollup-plugin-sass";
3
3
  import { Options } from "sass";
4
-
5
4
  //#region src/types.d.ts
6
5
  type RollupPluginSassOptions = NonNullable<Parameters<typeof sass>[0]>;
7
6
  interface PluginOptions extends Pick<RollupPluginSassOptions, 'include' | 'exclude'> {
@@ -17,4 +16,3 @@ interface SassPlugin extends Plugin {
17
16
  declare function createSassPlugin(options?: PluginOptions): SassPlugin;
18
17
  //#endregion
19
18
  export { createSassPlugin };
20
- //# sourceMappingURL=plugboy-sass-plugin.d.mts.map
@@ -19,18 +19,50 @@ function modulesPaths(absWorkingDir) {
19
19
  }
20
20
  //#endregion
21
21
  //#region src/plugin.ts
22
+ /**
23
+ * Concatenate the collected stylesheets in module execution order.
24
+ *
25
+ * rollup-plugin-sass appends each stylesheet to a flat array from its
26
+ * `transform` hook, then joins that array as-is. rolldown runs `transform`
27
+ * concurrently, so the array ends up in whatever order the transforms happened
28
+ * to finish and the emitted CSS differs between builds of identical sources —
29
+ * which matters, because that order is the cascade order.
30
+ *
31
+ * The bundle's module order is already stable, so use it as the key. Entries the
32
+ * module graph does not account for keep the order they were collected in, after
33
+ * the ones that could be placed.
34
+ */
35
+ function concatStylesInModuleOrder(entries, bundle) {
36
+ const position = /* @__PURE__ */ new Map();
37
+ for (const output of Object.values(bundle)) {
38
+ const chunk = output;
39
+ if (chunk.type !== "chunk" || !chunk.modules) continue;
40
+ for (const id of Object.keys(chunk.modules)) if (!position.has(id)) position.set(id, position.size);
41
+ }
42
+ return entries.map((entry, collectedAt) => ({
43
+ entry,
44
+ collectedAt
45
+ })).sort((a, b) => {
46
+ const pa = a.entry.id === void 0 ? void 0 : position.get(a.entry.id);
47
+ const pb = b.entry.id === void 0 ? void 0 : position.get(b.entry.id);
48
+ if (pa === void 0 && pb === void 0) return a.collectedAt - b.collectedAt;
49
+ if (pa === void 0) return 1;
50
+ if (pb === void 0) return -1;
51
+ return pa - pb;
52
+ }).map(({ entry }) => entry.content || "").join("");
53
+ }
22
54
  function createSassPlugin(options = {}) {
23
- let _styles = "";
55
+ let _styleEntries = [];
24
56
  const { sass: sassOptions, ...restOptions } = options;
25
57
  const { name: _name, generateBundle, ...sassPluginSettings } = sass({
26
58
  api: "modern",
27
59
  ...restOptions,
28
60
  options: {
29
61
  ...sassOptions,
30
- loadPaths: Array.from(new Set([...sassOptions?.loadPaths || modulesPaths()]))
62
+ loadPaths: Array.from(/* @__PURE__ */ new Set([...sassOptions?.loadPaths || modulesPaths()]))
31
63
  },
32
- output(styles) {
33
- _styles = styles;
64
+ output(_styles, entries) {
65
+ _styleEntries = entries;
34
66
  }
35
67
  });
36
68
  let _getWorkspace;
@@ -43,7 +75,8 @@ function createSassPlugin(options = {}) {
43
75
  } },
44
76
  async generateBundle(outputOptions, bundle, isWrite) {
45
77
  if (typeof generateBundle === "function") await generateBundle.call(this, outputOptions, bundle, isWrite);
46
- if (!_styles) return;
78
+ const styles = concatStylesInModuleOrder(_styleEntries, bundle);
79
+ if (!styles) return;
47
80
  let cssFile = outputOptions.file;
48
81
  if (!cssFile) {
49
82
  const cssExport = _getWorkspace()?.exports.find((e) => e.id.endsWith(".css"));
@@ -60,7 +93,7 @@ function createSassPlugin(options = {}) {
60
93
  type: "asset",
61
94
  name: cssFile,
62
95
  fileName: cssFile,
63
- source: _styles
96
+ source: styles
64
97
  });
65
98
  }
66
99
  });
@@ -1 +1 @@
1
- {"version":3,"file":"plugboy-sass-plugin.mjs","names":[],"sources":["../src/types.ts","../src/utils.ts","../src/plugin.ts"],"sourcesContent":["import { Plugin } from '@fastkit/plugboy';\nimport sass from 'rollup-plugin-sass';\nimport { type Options as SassOptions } from 'sass';\n\ntype RollupPluginSassOptions = NonNullable<Parameters<typeof sass>[0]>;\n\nexport interface PluginOptions extends Pick<\n RollupPluginSassOptions,\n 'include' | 'exclude'\n> {\n sass?: SassOptions<'async'>;\n}\n\nexport const PLUGIN_NAME = 'plugboy-sass';\n\nexport interface SassPlugin extends Plugin {\n name: typeof PLUGIN_NAME;\n _options: PluginOptions;\n}\n","import { parse, resolve } from 'path';\nimport { existsSync } from 'fs';\n\nexport function modulesPaths(absWorkingDir?: string): string[] {\n let path = absWorkingDir || process.cwd();\n const { root } = parse(path);\n const found: string[] = [];\n\n while (path !== root) {\n const filename = resolve(path, 'node_modules');\n if (existsSync(filename)) {\n found.push(filename);\n }\n path = resolve(path, '..');\n }\n return [...found];\n}\n","import { definePlugin, type TryGetWorkspace } from '@fastkit/plugboy';\nimport sass from 'rollup-plugin-sass';\nimport { PLUGIN_NAME, PluginOptions, SassPlugin } from './types';\nimport { modulesPaths } from './utils';\n\nexport function createSassPlugin(options: PluginOptions = {}) {\n let _styles = '';\n\n const { sass: sassOptions, ...restOptions } = options;\n\n const {\n name: _name,\n generateBundle,\n ...sassPluginSettings\n } = sass({\n api: 'modern',\n ...restOptions,\n options: {\n ...sassOptions,\n loadPaths: Array.from(\n new Set([...(sassOptions?.loadPaths || modulesPaths())]),\n ),\n },\n output(styles) {\n _styles = styles;\n },\n });\n\n let _getWorkspace: TryGetWorkspace;\n\n return definePlugin<SassPlugin>({\n name: PLUGIN_NAME,\n _options: options,\n ...(sassPluginSettings as any),\n hooks: {\n setupWorkspace(_, getWorkspace) {\n _getWorkspace = getWorkspace;\n },\n },\n async generateBundle(outputOptions, bundle, isWrite) {\n if (typeof generateBundle === 'function') {\n await generateBundle.call(\n this as any,\n outputOptions as any,\n bundle as any,\n isWrite,\n );\n }\n\n if (!_styles) return;\n\n let cssFile = outputOptions.file;\n\n if (!cssFile) {\n const workspace = _getWorkspace();\n\n const cssExport = workspace?.exports.find((e) => e.id.endsWith('.css'));\n if (cssExport) {\n const tmp = cssExport.id.split('/');\n cssFile = tmp[tmp.length - 1];\n } else {\n const fileNames = Object.keys(bundle);\n const jsFile = fileNames.find((f) => /\\.m?js$/.test(f));\n\n if (!jsFile) {\n return;\n }\n cssFile = jsFile.replace(/\\.m?js$/, '.css');\n }\n }\n this.emitFile({\n type: 'asset',\n name: cssFile,\n fileName: cssFile,\n source: _styles,\n });\n },\n });\n}\n"],"mappings":";;;;;AAaA,MAAa,cAAc;;;ACV3B,SAAgB,aAAa,eAAkC;CAC7D,IAAI,OAAO,iBAAiB,QAAQ,IAAI;CACxC,MAAM,EAAE,SAAS,MAAM,IAAI;CAC3B,MAAM,QAAkB,CAAC;CAEzB,OAAO,SAAS,MAAM;EACpB,MAAM,WAAW,QAAQ,MAAM,cAAc;EAC7C,IAAI,WAAW,QAAQ,GACrB,MAAM,KAAK,QAAQ;EAErB,OAAO,QAAQ,MAAM,IAAI;CAC3B;CACA,OAAO,CAAC,GAAG,KAAK;AAClB;;;ACXA,SAAgB,iBAAiB,UAAyB,CAAC,GAAG;CAC5D,IAAI,UAAU;CAEd,MAAM,EAAE,MAAM,aAAa,GAAG,gBAAgB;CAE9C,MAAM,EACJ,MAAM,OACN,gBACA,GAAG,uBACD,KAAK;EACP,KAAK;EACL,GAAG;EACH,SAAS;GACP,GAAG;GACH,WAAW,MAAM,KACf,IAAI,IAAI,CAAC,GAAI,aAAa,aAAa,aAAa,CAAE,CAAC,CACzD;EACF;EACA,OAAO,QAAQ;GACb,UAAU;EACZ;CACF,CAAC;CAED,IAAI;CAEJ,OAAO,aAAyB;EAC9B,MAAM;EACN,UAAU;EACV,GAAI;EACJ,OAAO,EACL,eAAe,GAAG,cAAc;GAC9B,gBAAgB;EAClB,EACF;EACA,MAAM,eAAe,eAAe,QAAQ,SAAS;GACnD,IAAI,OAAO,mBAAmB,YAC5B,MAAM,eAAe,KACnB,MACA,eACA,QACA,OACF;GAGF,IAAI,CAAC,SAAS;GAEd,IAAI,UAAU,cAAc;GAE5B,IAAI,CAAC,SAAS;IAGZ,MAAM,YAFY,cAEQ,CAAC,EAAE,QAAQ,MAAM,MAAM,EAAE,GAAG,SAAS,MAAM,CAAC;IACtE,IAAI,WAAW;KACb,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;KAClC,UAAU,IAAI,IAAI,SAAS;IAC7B,OAAO;KAEL,MAAM,SADY,OAAO,KAAK,MACP,CAAC,CAAC,MAAM,MAAM,UAAU,KAAK,CAAC,CAAC;KAEtD,IAAI,CAAC,QACH;KAEF,UAAU,OAAO,QAAQ,WAAW,MAAM;IAC5C;GACF;GACA,KAAK,SAAS;IACZ,MAAM;IACN,MAAM;IACN,UAAU;IACV,QAAQ;GACV,CAAC;EACH;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"plugboy-sass-plugin.mjs","names":[],"sources":["../src/types.ts","../src/utils.ts","../src/plugin.ts"],"sourcesContent":["import { Plugin } from '@fastkit/plugboy';\nimport sass from 'rollup-plugin-sass';\nimport { type Options as SassOptions } from 'sass';\n\ntype RollupPluginSassOptions = NonNullable<Parameters<typeof sass>[0]>;\n\nexport interface PluginOptions extends Pick<\n RollupPluginSassOptions,\n 'include' | 'exclude'\n> {\n sass?: SassOptions<'async'>;\n}\n\n/**\n * One stylesheet as collected by rollup-plugin-sass, handed to the `output`\n * callback alongside the concatenated result.\n */\nexport type SassStyleEntry = Parameters<\n Extract<NonNullable<RollupPluginSassOptions['output']>, (...args: any) => any>\n>[1][number];\n\nexport const PLUGIN_NAME = 'plugboy-sass';\n\nexport interface SassPlugin extends Plugin {\n name: typeof PLUGIN_NAME;\n _options: PluginOptions;\n}\n","import { parse, resolve } from 'path';\nimport { existsSync } from 'fs';\n\nexport function modulesPaths(absWorkingDir?: string): string[] {\n let path = absWorkingDir || process.cwd();\n const { root } = parse(path);\n const found: string[] = [];\n\n while (path !== root) {\n const filename = resolve(path, 'node_modules');\n if (existsSync(filename)) {\n found.push(filename);\n }\n path = resolve(path, '..');\n }\n return [...found];\n}\n","import { definePlugin, type TryGetWorkspace } from '@fastkit/plugboy';\nimport sass from 'rollup-plugin-sass';\nimport {\n PLUGIN_NAME,\n PluginOptions,\n SassPlugin,\n SassStyleEntry,\n} from './types';\nimport { modulesPaths } from './utils';\n\n/**\n * Concatenate the collected stylesheets in module execution order.\n *\n * rollup-plugin-sass appends each stylesheet to a flat array from its\n * `transform` hook, then joins that array as-is. rolldown runs `transform`\n * concurrently, so the array ends up in whatever order the transforms happened\n * to finish and the emitted CSS differs between builds of identical sources —\n * which matters, because that order is the cascade order.\n *\n * The bundle's module order is already stable, so use it as the key. Entries the\n * module graph does not account for keep the order they were collected in, after\n * the ones that could be placed.\n */\nfunction concatStylesInModuleOrder(\n entries: SassStyleEntry[],\n bundle: Record<string, unknown>,\n): string {\n const position = new Map<string, number>();\n\n for (const output of Object.values(bundle)) {\n const chunk = output as {\n type?: string;\n modules?: Record<string, unknown>;\n };\n if (chunk.type !== 'chunk' || !chunk.modules) continue;\n for (const id of Object.keys(chunk.modules)) {\n if (!position.has(id)) position.set(id, position.size);\n }\n }\n\n return entries\n .map((entry, collectedAt) => ({ entry, collectedAt }))\n .sort((a, b) => {\n const pa =\n a.entry.id === undefined ? undefined : position.get(a.entry.id);\n const pb =\n b.entry.id === undefined ? undefined : position.get(b.entry.id);\n if (pa === undefined && pb === undefined)\n return a.collectedAt - b.collectedAt;\n if (pa === undefined) return 1;\n if (pb === undefined) return -1;\n return pa - pb;\n })\n .map(({ entry }) => entry.content || '')\n .join('');\n}\n\nexport function createSassPlugin(options: PluginOptions = {}) {\n let _styleEntries: SassStyleEntry[] = [];\n\n const { sass: sassOptions, ...restOptions } = options;\n\n const {\n name: _name,\n generateBundle,\n ...sassPluginSettings\n } = sass({\n api: 'modern',\n ...restOptions,\n options: {\n ...sassOptions,\n loadPaths: Array.from(\n new Set([...(sassOptions?.loadPaths || modulesPaths())]),\n ),\n },\n // The joined string this also receives is built in transform-completion\n // order, so take the entries and join them ourselves.\n output(_styles, entries) {\n _styleEntries = entries;\n },\n });\n\n let _getWorkspace: TryGetWorkspace;\n\n return definePlugin<SassPlugin>({\n name: PLUGIN_NAME,\n _options: options,\n ...(sassPluginSettings as any),\n hooks: {\n setupWorkspace(_, getWorkspace) {\n _getWorkspace = getWorkspace;\n },\n },\n async generateBundle(outputOptions, bundle, isWrite) {\n if (typeof generateBundle === 'function') {\n await generateBundle.call(\n this as any,\n outputOptions as any,\n bundle as any,\n isWrite,\n );\n }\n\n const styles = concatStylesInModuleOrder(_styleEntries, bundle);\n if (!styles) return;\n\n let cssFile = outputOptions.file;\n\n if (!cssFile) {\n const workspace = _getWorkspace();\n\n const cssExport = workspace?.exports.find((e) => e.id.endsWith('.css'));\n if (cssExport) {\n const tmp = cssExport.id.split('/');\n cssFile = tmp[tmp.length - 1];\n } else {\n const fileNames = Object.keys(bundle);\n const jsFile = fileNames.find((f) => /\\.m?js$/.test(f));\n\n if (!jsFile) {\n return;\n }\n cssFile = jsFile.replace(/\\.m?js$/, '.css');\n }\n }\n this.emitFile({\n type: 'asset',\n name: cssFile,\n fileName: cssFile,\n source: styles,\n });\n },\n });\n}\n"],"mappings":";;;;;AAqBA,MAAa,cAAc;;;AClB3B,SAAgB,aAAa,eAAkC;CAC7D,IAAI,OAAO,iBAAiB,QAAQ,IAAI;CACxC,MAAM,EAAE,SAAS,MAAM,IAAI;CAC3B,MAAM,QAAkB,CAAC;CAEzB,OAAO,SAAS,MAAM;EACpB,MAAM,WAAW,QAAQ,MAAM,cAAc;EAC7C,IAAI,WAAW,QAAQ,GACrB,MAAM,KAAK,QAAQ;EAErB,OAAO,QAAQ,MAAM,IAAI;CAC3B;CACA,OAAO,CAAC,GAAG,KAAK;AAClB;;;;;;;;;;;;;;;;ACOA,SAAS,0BACP,SACA,QACQ;CACR,MAAM,2BAAW,IAAI,IAAoB;CAEzC,KAAK,MAAM,UAAU,OAAO,OAAO,MAAM,GAAG;EAC1C,MAAM,QAAQ;EAId,IAAI,MAAM,SAAS,WAAW,CAAC,MAAM,SAAS;EAC9C,KAAK,MAAM,MAAM,OAAO,KAAK,MAAM,OAAO,GACxC,IAAI,CAAC,SAAS,IAAI,EAAE,GAAG,SAAS,IAAI,IAAI,SAAS,IAAI;CAEzD;CAEA,OAAO,QACJ,KAAK,OAAO,iBAAiB;EAAE;EAAO;CAAY,EAAE,CAAC,CACrD,MAAM,GAAG,MAAM;EACd,MAAM,KACJ,EAAE,MAAM,OAAO,KAAA,IAAY,KAAA,IAAY,SAAS,IAAI,EAAE,MAAM,EAAE;EAChE,MAAM,KACJ,EAAE,MAAM,OAAO,KAAA,IAAY,KAAA,IAAY,SAAS,IAAI,EAAE,MAAM,EAAE;EAChE,IAAI,OAAO,KAAA,KAAa,OAAO,KAAA,GAC7B,OAAO,EAAE,cAAc,EAAE;EAC3B,IAAI,OAAO,KAAA,GAAW,OAAO;EAC7B,IAAI,OAAO,KAAA,GAAW,OAAO;EAC7B,OAAO,KAAK;CACd,CAAC,CAAC,CACD,KAAK,EAAE,YAAY,MAAM,WAAW,EAAE,CAAC,CACvC,KAAK,EAAE;AACZ;AAEA,SAAgB,iBAAiB,UAAyB,CAAC,GAAG;CAC5D,IAAI,gBAAkC,CAAC;CAEvC,MAAM,EAAE,MAAM,aAAa,GAAG,gBAAgB;CAE9C,MAAM,EACJ,MAAM,OACN,gBACA,GAAG,uBACD,KAAK;EACP,KAAK;EACL,GAAG;EACH,SAAS;GACP,GAAG;GACH,WAAW,MAAM,qBACf,IAAI,IAAI,CAAC,GAAI,aAAa,aAAa,aAAa,CAAE,CAAC,CACzD;EACF;EAGA,OAAO,SAAS,SAAS;GACvB,gBAAgB;EAClB;CACF,CAAC;CAED,IAAI;CAEJ,OAAO,aAAyB;EAC9B,MAAM;EACN,UAAU;EACV,GAAI;EACJ,OAAO,EACL,eAAe,GAAG,cAAc;GAC9B,gBAAgB;EAClB,EACF;EACA,MAAM,eAAe,eAAe,QAAQ,SAAS;GACnD,IAAI,OAAO,mBAAmB,YAC5B,MAAM,eAAe,KACnB,MACA,eACA,QACA,OACF;GAGF,MAAM,SAAS,0BAA0B,eAAe,MAAM;GAC9D,IAAI,CAAC,QAAQ;GAEb,IAAI,UAAU,cAAc;GAE5B,IAAI,CAAC,SAAS;IAGZ,MAAM,YAFY,cAEQ,CAAC,EAAE,QAAQ,MAAM,MAAM,EAAE,GAAG,SAAS,MAAM,CAAC;IACtE,IAAI,WAAW;KACb,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;KAClC,UAAU,IAAI,IAAI,SAAS;IAC7B,OAAO;KAEL,MAAM,SADY,OAAO,KAAK,MACP,CAAC,CAAC,MAAM,MAAM,UAAU,KAAK,CAAC,CAAC;KAEtD,IAAI,CAAC,QACH;KAEF,UAAU,OAAO,QAAQ,WAAW,MAAM;IAC5C;GACF;GACA,KAAK,SAAS;IACZ,MAAM;IACN,MAAM;IACN,UAAU;IACV,QAAQ;GACV,CAAC;EACH;CACF,CAAC;AACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastkit/plugboy-sass-plugin",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "plugboy-sass-plugin",
5
5
  "keywords": [
6
6
  "plugboy",
@@ -37,13 +37,13 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "rollup-plugin-sass": "^1.15.3",
40
- "sass": "^1.101.0"
40
+ "sass": "^1.102.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@fastkit/plugboy": "^1.0.0"
43
+ "@fastkit/plugboy": "^1.2.2"
44
44
  },
45
45
  "peerDependencies": {
46
- "@fastkit/plugboy": "^1.0.0"
46
+ "@fastkit/plugboy": "^1.2.2"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "plugboy build",