@eik/postcss-plugin 4.0.0 → 4.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [4.0.2](https://github.com/eik-lib/postcss-import-map/compare/v4.0.1...v4.0.2) (2024-08-12)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **deps:** update dependency @eik/common to v4.0.8 ([169bffa](https://github.com/eik-lib/postcss-import-map/commit/169bffa9abe95c6d79e5987c679f4e1e619e94ee))
7
+
8
+ ## [4.0.1](https://github.com/eik-lib/postcss-import-map/compare/v4.0.0...v4.0.1) (2024-08-09)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * include type definitions ([7ad7a16](https://github.com/eik-lib/postcss-import-map/commit/7ad7a16ea7f4ca246383cf1b8797f45b0dd2995d))
14
+
1
15
  # [4.0.0](https://github.com/eik-lib/postcss-import-map/compare/v3.0.14...v4.0.0) (2024-07-29)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,19 +1,25 @@
1
1
  {
2
2
  "name": "@eik/postcss-plugin",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "description": "PostCSS plugin that uses Eik defined import map files to transform bare import specifiers to absolute URLs in @import rules",
5
5
  "main": "src/plugin.js",
6
+ "types": "./types/plugin.d.ts",
6
7
  "type": "module",
7
8
  "files": [
8
9
  "CHANGELOG.md",
9
10
  "package.json",
10
- "src/"
11
+ "src/",
12
+ "types/"
11
13
  ],
12
14
  "scripts": {
15
+ "clean": "rimraf .tap node_modules types",
13
16
  "test": "tap test/*.js --disable-coverage --allow-empty-coverage",
14
17
  "test:snapshot": "TAP_SNAPSHOT=1 tap test/*.js --disable-coverage --allow-empty-coverage",
15
18
  "lint": "eslint .",
16
- "lint:fix": "eslint . --fix"
19
+ "lint:fix": "eslint . --fix",
20
+ "types": "run-s types:module types:test",
21
+ "types:module": "tsc",
22
+ "types:test": "tsc --project tsconfig.test.json"
17
23
  },
18
24
  "repository": {
19
25
  "type": "git",
@@ -33,25 +39,23 @@
33
39
  },
34
40
  "homepage": "https://github.com/eik-lib/postcss-import-map#readme",
35
41
  "devDependencies": {
36
- "@semantic-release/changelog": "6.0.3",
37
- "@semantic-release/commit-analyzer": "13.0.0",
38
- "@semantic-release/git": "10.0.1",
39
- "@semantic-release/github": "10.1.3",
40
- "@semantic-release/npm": "12.0.1",
41
- "@semantic-release/release-notes-generator": "14.0.1",
42
- "eslint": "9.8.0",
43
- "eslint-config-prettier": "9.1.0",
44
- "eslint-plugin-prettier": "5.2.1",
42
+ "@eik/eslint-config": "1.0.2",
43
+ "@eik/prettier-config": "1.0.1",
44
+ "@eik/semantic-release-config": "1.0.0",
45
+ "@eik/typescript-config": "1.0.0",
46
+ "eslint": "9.9.0",
45
47
  "fastify": "4.28.1",
46
- "globals": "15.8.0",
47
- "postcss": "8.4.40",
48
- "rollup": "4.19.1",
49
- "semantic-release": "24.0.0",
48
+ "npm-run-all2": "5.0.0",
49
+ "postcss": "8.4.41",
50
50
  "prettier": "3.3.3",
51
- "tap": "20.0.3"
51
+ "rimraf": "6.0.1",
52
+ "rollup": "4.20.0",
53
+ "semantic-release": "24.0.0",
54
+ "tap": "20.0.3",
55
+ "typescript": "5.5.4"
52
56
  },
53
57
  "dependencies": {
54
- "@eik/common-config-loader": "4.0.0-next.12",
58
+ "@eik/common": "4.0.8",
55
59
  "css-url-parser": "1.1.3"
56
60
  },
57
61
  "peerDependencies": {
package/src/plugin.js CHANGED
@@ -1,118 +1,163 @@
1
- import parseCssUrls from 'css-url-parser';
2
- import { getDefaults } from '@eik/common-config-loader';
3
-
4
- const notUrl = (url) => url.substr(0, 4) !== 'http';
5
-
1
+ import parseCssUrls from "css-url-parser";
2
+ import { helpers } from "@eik/common";
3
+
4
+ /**
5
+ * @param {string} url
6
+ * @returns {boolean}
7
+ */
8
+ const notUrl = (url) => url.substr(0, 4) !== "http";
9
+
10
+ /**
11
+ * @typedef {object} ImportMap
12
+ * @property {Record<string, string>} imports
13
+ */
14
+
15
+ /**
16
+ * @param {string[]} urls
17
+ * @returns {Promise<ImportMap[]>}
18
+ */
6
19
  async function fetchImportMaps(urls = []) {
7
- try {
8
- const maps = urls.map((map) =>
9
- fetch(map).then((result) => {
10
- if (result.status === 404) {
11
- throw new Error('Import map could not be found on server');
12
- } else if (result.status >= 400 && result.status < 500) {
13
- throw new Error('Server rejected client request');
14
- } else if (result.status >= 500) {
15
- throw new Error('Server error');
16
- }
17
- return result.json();
18
- }),
19
- );
20
- return await Promise.all(maps);
21
- } catch (err) {
22
- throw new Error(
23
- `Unable to load import map file from server: ${err.message}`,
24
- );
25
- }
20
+ try {
21
+ const maps = urls.map((map) =>
22
+ fetch(map).then((result) => {
23
+ if (result.status === 404) {
24
+ throw new Error("Import map could not be found on server");
25
+ } else if (result.status >= 400 && result.status < 500) {
26
+ throw new Error("Server rejected client request");
27
+ } else if (result.status >= 500) {
28
+ throw new Error("Server error");
29
+ }
30
+ return /** @type {Promise<ImportMap>} */ (result.json());
31
+ }),
32
+ );
33
+ return await Promise.all(maps);
34
+ } catch (err) {
35
+ throw new Error(
36
+ `Unable to load import map file from server: ${err.message}`,
37
+ );
38
+ }
26
39
  }
27
40
 
41
+ /**
42
+ * @param {ImportMap} map
43
+ * @returns {Array<{ key: string; value: string; }>}
44
+ */
28
45
  const validate = (map) =>
29
- Object.keys(map.imports).map((key) => {
30
- const value = map.imports[key];
31
-
32
- if (notUrl(value)) {
33
- throw Error(
34
- `Import specifier can NOT be mapped to a bare import statement. Import specifier "${key}" is being wrongly mapped to "${value}"`,
35
- );
36
- }
37
-
38
- return { key, value };
39
- });
40
-
46
+ Object.keys(map.imports).map((key) => {
47
+ const value = map.imports[key];
48
+
49
+ if (notUrl(value)) {
50
+ throw Error(
51
+ `Import specifier can NOT be mapped to a bare import statement. Import specifier "${key}" is being wrongly mapped to "${value}"`,
52
+ );
53
+ }
54
+
55
+ return { key, value };
56
+ });
57
+
58
+ /**
59
+ * @typedef {object} PluginOptions
60
+ * @property {string} [path=process.cwd()]
61
+ * @property {string[]} [urls=[]] URLs to import maps hosted on an Eik server. Takes precedence over `eik.json`.
62
+ * @property {ImportMap[]} [maps=[]] Inline import maps that should be used. Takes precedence over `urls` and `eik.json`.
63
+ */
64
+
65
+ /**
66
+ * @typedef {object} PrepareResult
67
+ * @property {(root: import('postcss').Root) => Promise<void>} Once
68
+ * @property {{ import: (decl: import('postcss').AtRule) => Promise<void> }} AtRule
69
+ */
70
+
71
+ /**
72
+ * @typedef {object} Plugin
73
+ * @property {string} postcssPlugin
74
+ * @property {() => PrepareResult} prepare
75
+ */
76
+
77
+ /**
78
+ * Returns the plugin which will apply the given import maps during the build.
79
+ * @param {PluginOptions} options
80
+ * @returns {Plugin}
81
+ */
41
82
  export default ({ path = process.cwd(), maps = [], urls = [] } = {}) => {
42
- const pMaps = Array.isArray(maps) ? maps : [maps];
43
- const pUrls = Array.isArray(urls) ? urls : [urls];
44
-
45
- return {
46
- postcssPlugin: '@eik/postcss-import-map',
47
- prepare() {
48
- // Avoid parsing things more than necessary
49
- const processed = new WeakMap();
50
- // Only replace once per url
51
- const replaced = new Set();
52
- // Eagerly start resolving
53
-
54
- // Reused replace logic
55
- const applyImportMap = (mapping, decl) => {
56
- if (processed.has(decl)) {
57
- return;
58
- }
59
-
60
- let key;
61
- // First check if it's possibly using syntax like url()
62
- const parsedUrls = parseCssUrls(decl.params);
63
- if (parsedUrls.length > 0) {
64
- key = parsedUrls[0];
65
- } else {
66
- // Handle the common cases where it's not wrapped in url() but may have quotes
67
- key = decl.params.replace(/["']/g, '');
68
- }
69
-
70
- // Webpack interop
71
- key = key.replace(/^~/, '');
72
-
73
- if (replaced.has(key)) {
74
- decl.remove();
75
- } else if (mapping.has(key)) {
76
- decl.params = `'${mapping.get(key)}'`;
77
- replaced.add(key);
78
- }
79
-
80
- // Cache we've processed this
81
- processed.set(decl, true);
82
- };
83
-
84
- const mapping = new Map();
85
-
86
- return {
87
- // Run initially once, this is to ensure it runs before postcss-import
88
- async Once(root) {
89
- // Load eik config from eik.json or package.json
90
- const config = await getDefaults(path);
91
-
92
- // Fetch import maps from the server
93
- const fetched = await fetchImportMaps([
94
- ...config.map,
95
- ...pUrls,
96
- ]);
97
-
98
- const allImportMaps = [...fetched, ...pMaps];
99
- allImportMaps.forEach((item) => {
100
- const i = validate(item);
101
- i.forEach((obj) => {
102
- mapping.set(obj.key, obj.value);
103
- });
104
- });
105
-
106
- root.walkAtRules('import', (decl) => {
107
- applyImportMap(mapping, decl);
108
- });
109
- },
110
- AtRule: {
111
- import: async (decl) => {
112
- applyImportMap(mapping, decl);
113
- },
114
- },
115
- };
116
- },
117
- };
83
+ const pMaps = Array.isArray(maps) ? maps : [maps];
84
+ const pUrls = Array.isArray(urls) ? urls : [urls];
85
+
86
+ return {
87
+ postcssPlugin: "@eik/postcss-import-map",
88
+ prepare() {
89
+ // Avoid parsing things more than necessary
90
+ const processed = new WeakMap();
91
+ // Only replace once per url
92
+ const replaced = new Set();
93
+ // Eagerly start resolving
94
+
95
+ // Reused replace logic
96
+ /**
97
+ *
98
+ * @param {Map<string, string>} mapping
99
+ * @param {import('postcss').AtRule} decl
100
+ * @returns {void}
101
+ */
102
+ const applyImportMap = (mapping, decl) => {
103
+ if (processed.has(decl)) {
104
+ return;
105
+ }
106
+
107
+ let key;
108
+ // First check if it's possibly using syntax like url()
109
+ const parsedUrls = parseCssUrls(decl.params);
110
+ if (parsedUrls.length > 0) {
111
+ key = parsedUrls[0];
112
+ } else {
113
+ // Handle the common cases where it's not wrapped in url() but may have quotes
114
+ key = decl.params.replace(/["']/g, "");
115
+ }
116
+
117
+ // Webpack interop
118
+ key = key.replace(/^~/, "");
119
+
120
+ if (replaced.has(key)) {
121
+ decl.remove();
122
+ } else if (mapping.has(key)) {
123
+ decl.params = `'${mapping.get(key)}'`;
124
+ replaced.add(key);
125
+ }
126
+
127
+ // Cache we've processed this
128
+ processed.set(decl, true);
129
+ };
130
+
131
+ /** @type {Map<string, string>} */
132
+ const mapping = new Map();
133
+
134
+ return {
135
+ // Run initially once, this is to ensure it runs before postcss-import
136
+ async Once(root) {
137
+ // Load eik config from eik.json or package.json
138
+ const config = await helpers.getDefaults(path);
139
+
140
+ // Fetch import maps from the server
141
+ const fetched = await fetchImportMaps([...config.map, ...pUrls]);
142
+
143
+ const allImportMaps = [...fetched, ...pMaps];
144
+ allImportMaps.forEach((item) => {
145
+ const i = validate(item);
146
+ i.forEach((obj) => {
147
+ mapping.set(obj.key, obj.value);
148
+ });
149
+ });
150
+
151
+ root.walkAtRules("import", (decl) => {
152
+ applyImportMap(mapping, decl);
153
+ });
154
+ },
155
+ AtRule: {
156
+ import: async (decl) => {
157
+ applyImportMap(mapping, decl);
158
+ },
159
+ },
160
+ };
161
+ },
162
+ };
118
163
  };
@@ -0,0 +1,26 @@
1
+ declare function _default({ path, maps, urls }?: PluginOptions): Plugin;
2
+ export default _default;
3
+ export type ImportMap = {
4
+ imports: Record<string, string>;
5
+ };
6
+ export type PluginOptions = {
7
+ path?: string;
8
+ /**
9
+ * URLs to import maps hosted on an Eik server. Takes precedence over `eik.json`.
10
+ */
11
+ urls?: string[];
12
+ /**
13
+ * Inline import maps that should be used. Takes precedence over `urls` and `eik.json`.
14
+ */
15
+ maps?: ImportMap[];
16
+ };
17
+ export type PrepareResult = {
18
+ Once: (root: import("postcss").Root) => Promise<void>;
19
+ AtRule: {
20
+ import: (decl: import("postcss").AtRule) => Promise<void>;
21
+ };
22
+ };
23
+ export type Plugin = {
24
+ postcssPlugin: string;
25
+ prepare: () => PrepareResult;
26
+ };