@vltpkg/query 0.0.0-0.1730724342581 → 0.0.0-3

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 (46) hide show
  1. package/README.md +8 -0
  2. package/dist/esm/attribute.d.ts +2 -2
  3. package/dist/esm/attribute.d.ts.map +1 -1
  4. package/dist/esm/attribute.js +11 -4
  5. package/dist/esm/attribute.js.map +1 -1
  6. package/dist/esm/class.d.ts +1 -1
  7. package/dist/esm/class.d.ts.map +1 -1
  8. package/dist/esm/class.js +2 -1
  9. package/dist/esm/class.js.map +1 -1
  10. package/dist/esm/combinator.d.ts +1 -1
  11. package/dist/esm/combinator.d.ts.map +1 -1
  12. package/dist/esm/combinator.js +2 -1
  13. package/dist/esm/combinator.js.map +1 -1
  14. package/dist/esm/id.d.ts +1 -1
  15. package/dist/esm/id.d.ts.map +1 -1
  16. package/dist/esm/id.js +2 -2
  17. package/dist/esm/id.js.map +1 -1
  18. package/dist/esm/index.d.ts +7 -5
  19. package/dist/esm/index.d.ts.map +1 -1
  20. package/dist/esm/index.js +20 -9
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/esm/pseudo/attr.d.ts +18 -0
  23. package/dist/esm/pseudo/attr.d.ts.map +1 -0
  24. package/dist/esm/pseudo/attr.js +50 -0
  25. package/dist/esm/pseudo/attr.js.map +1 -0
  26. package/dist/esm/pseudo/helpers.d.ts +15 -0
  27. package/dist/esm/pseudo/helpers.d.ts.map +1 -0
  28. package/dist/esm/pseudo/helpers.js +24 -0
  29. package/dist/esm/pseudo/helpers.js.map +1 -0
  30. package/dist/esm/pseudo/outdated.d.ts +54 -0
  31. package/dist/esm/pseudo/outdated.d.ts.map +1 -0
  32. package/dist/esm/pseudo/outdated.js +201 -0
  33. package/dist/esm/pseudo/outdated.js.map +1 -0
  34. package/dist/esm/pseudo/semver.d.ts +16 -0
  35. package/dist/esm/pseudo/semver.d.ts.map +1 -0
  36. package/dist/esm/pseudo/semver.js +180 -0
  37. package/dist/esm/pseudo/semver.js.map +1 -0
  38. package/dist/esm/pseudo.d.ts +1 -8
  39. package/dist/esm/pseudo.d.ts.map +1 -1
  40. package/dist/esm/pseudo.js +14 -63
  41. package/dist/esm/pseudo.js.map +1 -1
  42. package/dist/esm/types.d.ts +8 -2
  43. package/dist/esm/types.d.ts.map +1 -1
  44. package/dist/esm/types.js +13 -0
  45. package/dist/esm/types.js.map +1 -1
  46. package/package.json +25 -17
@@ -0,0 +1,54 @@
1
+ import type { NodeLike } from '@vltpkg/graph';
2
+ import type { SpecOptions } from '@vltpkg/spec/browser';
3
+ import type { ParserState, PostcssNode } from '../types.ts';
4
+ /**
5
+ * The possible values accepted by the :outdated() pseudo selector.
6
+ */
7
+ export type OutdatedKinds = 'any' | 'major' | 'minor' | 'patch' | 'in-range' | 'out-of-range';
8
+ /**
9
+ * Result of the internal parsing of the :outdated() pseudo selector.
10
+ */
11
+ export type OutdatedInternals = {
12
+ kind: OutdatedKinds;
13
+ };
14
+ /**
15
+ * Extracts a semver type from a version string.
16
+ */
17
+ export type SemverTypeExtraction = (version: string) => number | undefined;
18
+ /**
19
+ * Checks if a string is a valid {@link OutdatedKinds}.
20
+ */
21
+ export declare const isOutdatedKind: (value: string) => value is OutdatedKinds;
22
+ /**
23
+ * Asserts that a string is a valid {@link OutdatedKinds}.
24
+ */
25
+ export declare const asOutdatedKind: (value: string) => OutdatedKinds;
26
+ /**
27
+ * Fetches the available versions of a package from the npm registry.
28
+ */
29
+ export declare const retrieveRemoteVersions: (node: NodeLike, specOptions: SpecOptions) => Promise<string[]>;
30
+ /**
31
+ * Retrieves what kind of check the :outdated selector should perform.
32
+ */
33
+ export declare const parseInternals: (nodes: PostcssNode[]) => OutdatedInternals;
34
+ /**
35
+ * Filter nodes by queueing up for removal those that are not outdated.
36
+ */
37
+ export declare const queueNode: (state: ParserState, node: NodeLike, kind: OutdatedKinds) => Promise<NodeLike | undefined>;
38
+ /**
39
+ * Filters out nodes that are not outdated.
40
+ *
41
+ * The :outdated() pseudo selector supports one `type` argument,
42
+ * possible values are the following:
43
+ *
44
+ * - `any`: Selects all nodes that have a greater version available.
45
+ * - `major`: Selects all nodes that have a greater major version available.
46
+ * - `minor`: Selects all nodes that have a greater minor version available.
47
+ * - `patch`: Selects all nodes that have a greater patch version available.
48
+ * - `in-range`: Selects all nodes that have a parent node with a spec definition
49
+ * that satisfies one of the available remote versions.
50
+ * - `out-of-range`: Selects all nodes that have a parent node with a spec definition
51
+ * that does not satisfy any of the available remote versions.
52
+ */
53
+ export declare const outdated: (state: ParserState) => Promise<ParserState>;
54
+ //# sourceMappingURL=outdated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outdated.d.ts","sourceRoot":"","sources":["../../../src/pseudo/outdated.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAiBvD,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAG3D;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,KAAK,GACL,OAAO,GACP,OAAO,GACP,OAAO,GACP,UAAU,GACV,cAAc,CAAA;AAElB;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,aAAa,CAAA;CACpB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CACjC,OAAO,EAAE,MAAM,KACZ,MAAM,GAAG,SAAS,CAAA;AAWvB;;GAEG;AACH,eAAO,MAAM,cAAc,UAClB,MAAM,KACZ,KAAK,IAAI,aAAkD,CAAA;AAE9D;;GAEG;AACH,eAAO,MAAM,cAAc,UAAW,MAAM,KAAG,aAQ9C,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,SAC3B,QAAQ,eACD,WAAW,KACvB,OAAO,CAAC,MAAM,EAAE,CAyClB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,UAClB,WAAW,EAAE,KACnB,iBAmBF,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,UACb,WAAW,QACZ,QAAQ,QACR,aAAa,KAClB,OAAO,CAAC,QAAQ,GAAG,SAAS,CAsF9B,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,UAAiB,WAAW,yBAwChD,CAAA"}
@@ -0,0 +1,201 @@
1
+ import { hydrate, splitDepID } from '@vltpkg/dep-id/browser';
2
+ import { error } from '@vltpkg/error-cause';
3
+ import { compare, gt, major, minor, patch, satisfies, } from '@vltpkg/semver';
4
+ import { asPostcssNodeWithChildren, asStringNode, asTagNode, isStringNode, isTagNode, } from "../types.js";
5
+ import { removeNode, removeQuotes } from "./helpers.js";
6
+ const kinds = new Set([
7
+ 'any',
8
+ 'major',
9
+ 'minor',
10
+ 'patch',
11
+ 'in-range',
12
+ 'out-of-range',
13
+ ]);
14
+ /**
15
+ * Checks if a string is a valid {@link OutdatedKinds}.
16
+ */
17
+ export const isOutdatedKind = (value) => kinds.has(value);
18
+ /**
19
+ * Asserts that a string is a valid {@link OutdatedKinds}.
20
+ */
21
+ export const asOutdatedKind = (value) => {
22
+ if (!isOutdatedKind(value)) {
23
+ throw error('Expected a valid outdated kind', {
24
+ found: value,
25
+ validOptions: Array.from(kinds),
26
+ });
27
+ }
28
+ return value;
29
+ };
30
+ /**
31
+ * Fetches the available versions of a package from the npm registry.
32
+ */
33
+ export const retrieveRemoteVersions = async (node, specOptions) => {
34
+ const spec = hydrate(node.id, String(node.name), specOptions);
35
+ if (!spec.registry || !node.name) {
36
+ return [];
37
+ }
38
+ const url = new URL(spec.registry);
39
+ url.pathname = `/${node.name}`;
40
+ try {
41
+ const response = await fetch(String(url), {
42
+ headers: {
43
+ Accept: 'application/vnd.npm.install-v1+json',
44
+ },
45
+ });
46
+ if (!response.ok) {
47
+ // eslint-disable-next-line no-console
48
+ console.warn(error('Failed to fetch packument', {
49
+ name: String(node.name),
50
+ spec,
51
+ response,
52
+ }));
53
+ return [];
54
+ }
55
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
56
+ const packument = await response.json();
57
+ return Object.keys(packument.versions).sort(compare);
58
+ }
59
+ catch (e) {
60
+ const err = e;
61
+ // eslint-disable-next-line no-console
62
+ console.warn(error('Could not retrieve registry versions', {
63
+ name: String(node.name),
64
+ spec,
65
+ cause: err,
66
+ }));
67
+ return [];
68
+ }
69
+ };
70
+ /**
71
+ * Retrieves what kind of check the :outdated selector should perform.
72
+ */
73
+ export const parseInternals = (nodes) => {
74
+ let kind = 'any';
75
+ if (isStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])) {
76
+ kind = asOutdatedKind(removeQuotes(asStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])
77
+ .value));
78
+ }
79
+ else if (isTagNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])) {
80
+ kind = asOutdatedKind(asTagNode(asPostcssNodeWithChildren(nodes[0]).nodes[0]).value);
81
+ }
82
+ return { kind };
83
+ };
84
+ /**
85
+ * Filter nodes by queueing up for removal those that are not outdated.
86
+ */
87
+ export const queueNode = async (state, node, kind) => {
88
+ if (!node.name || !node.version) {
89
+ return node;
90
+ }
91
+ const nodeVersion = node.version;
92
+ const versions = await retrieveRemoteVersions(node, state.specOptions);
93
+ const greaterVersions = versions.filter((version) => gt(version, nodeVersion));
94
+ // if there are no greater versions, then the node is not outdated
95
+ if (!greaterVersions.length) {
96
+ return node;
97
+ }
98
+ const checkKind = new Map([
99
+ ['major', major],
100
+ ['minor', minor],
101
+ ['patch', patch],
102
+ ]);
103
+ switch (kind) {
104
+ case 'any':
105
+ return;
106
+ case 'major':
107
+ case 'minor':
108
+ case 'patch': {
109
+ return (greaterVersions.some((version) => {
110
+ const va = checkKind.get(kind)?.(version);
111
+ const vb = checkKind.get(kind)?.(nodeVersion);
112
+ /* c8 ignore next - impossible but typescript doesn't know */
113
+ if (va === undefined || vb === undefined)
114
+ return false;
115
+ return va > vb;
116
+ })) ?
117
+ undefined
118
+ : node;
119
+ }
120
+ // the node should be part of the result as long as it has at least
121
+ // one parent node that has a spec definition that satisfies one
122
+ // of the available remove versions
123
+ case 'in-range': {
124
+ for (const edge of node.edgesIn) {
125
+ // if the edge is not part of the partial results, skip it
126
+ /* c8 ignore next */
127
+ if (!state.partial.edges.has(edge))
128
+ continue;
129
+ if (greaterVersions.some(version => edge.spec.final.range &&
130
+ satisfies(version, edge.spec.final.range))) {
131
+ return;
132
+ }
133
+ }
134
+ return node;
135
+ }
136
+ // the node is part of the result as long as none of its parents has
137
+ // a spec definition that satisfies one of the available remote versions
138
+ case 'out-of-range': {
139
+ for (const edge of node.edgesIn) {
140
+ // if the edge is not part of the partial results, skip it
141
+ /* c8 ignore next */
142
+ if (!state.partial.edges.has(edge))
143
+ continue;
144
+ if (greaterVersions.some(version => edge.spec.final.range &&
145
+ satisfies(version, edge.spec.final.range))) {
146
+ return node;
147
+ }
148
+ }
149
+ return;
150
+ }
151
+ }
152
+ };
153
+ /**
154
+ * Filters out nodes that are not outdated.
155
+ *
156
+ * The :outdated() pseudo selector supports one `type` argument,
157
+ * possible values are the following:
158
+ *
159
+ * - `any`: Selects all nodes that have a greater version available.
160
+ * - `major`: Selects all nodes that have a greater major version available.
161
+ * - `minor`: Selects all nodes that have a greater minor version available.
162
+ * - `patch`: Selects all nodes that have a greater patch version available.
163
+ * - `in-range`: Selects all nodes that have a parent node with a spec definition
164
+ * that satisfies one of the available remote versions.
165
+ * - `out-of-range`: Selects all nodes that have a parent node with a spec definition
166
+ * that does not satisfy any of the available remote versions.
167
+ */
168
+ export const outdated = async (state) => {
169
+ let internals;
170
+ try {
171
+ internals = parseInternals(asPostcssNodeWithChildren(state.current).nodes);
172
+ }
173
+ catch (err) {
174
+ throw error('Failed to parse :outdated selector', {
175
+ cause: err,
176
+ });
177
+ }
178
+ const { kind } = internals;
179
+ const queue = [];
180
+ for (const node of state.partial.nodes) {
181
+ // filter out nodes that are always ignored by the outdated selector
182
+ if (node.mainImporter ||
183
+ node.manifest?.private ||
184
+ splitDepID(node.id)[0] !== 'registry') {
185
+ removeNode(state, node);
186
+ continue;
187
+ }
188
+ // fetchs outdated info and performs checks to define
189
+ // whether or not a node should be filtered out
190
+ queue.push(queueNode(state, node, kind));
191
+ }
192
+ // nodes queued for removal are then finally removed
193
+ const removeNodeQueue = await Promise.all(queue);
194
+ for (const node of removeNodeQueue) {
195
+ if (node) {
196
+ removeNode(state, node);
197
+ }
198
+ }
199
+ return state;
200
+ };
201
+ //# sourceMappingURL=outdated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outdated.js","sourceRoot":"","sources":["../../../src/pseudo/outdated.ts"],"names":[],"mappings":"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","sourcesContent":["import { hydrate, splitDepID } from '@vltpkg/dep-id/browser'\nimport { error } from '@vltpkg/error-cause'\nimport type { NodeLike } from '@vltpkg/graph'\nimport type { SpecOptions } from '@vltpkg/spec/browser'\nimport {\n compare,\n gt,\n major,\n minor,\n patch,\n satisfies,\n} from '@vltpkg/semver'\nimport type { Packument } from '@vltpkg/types'\nimport {\n asPostcssNodeWithChildren,\n asStringNode,\n asTagNode,\n isStringNode,\n isTagNode,\n} from '../types.ts'\nimport type { ParserState, PostcssNode } from '../types.ts'\nimport { removeNode, removeQuotes } from './helpers.ts'\n\n/**\n * The possible values accepted by the :outdated() pseudo selector.\n */\nexport type OutdatedKinds =\n | 'any'\n | 'major'\n | 'minor'\n | 'patch'\n | 'in-range'\n | 'out-of-range'\n\n/**\n * Result of the internal parsing of the :outdated() pseudo selector.\n */\nexport type OutdatedInternals = {\n kind: OutdatedKinds\n}\n\n/**\n * Extracts a semver type from a version string.\n */\nexport type SemverTypeExtraction = (\n version: string,\n) => number | undefined\n\nconst kinds = new Set<OutdatedKinds>([\n 'any',\n 'major',\n 'minor',\n 'patch',\n 'in-range',\n 'out-of-range',\n])\n\n/**\n * Checks if a string is a valid {@link OutdatedKinds}.\n */\nexport const isOutdatedKind = (\n value: string,\n): value is OutdatedKinds => kinds.has(value as OutdatedKinds)\n\n/**\n * Asserts that a string is a valid {@link OutdatedKinds}.\n */\nexport const asOutdatedKind = (value: string): OutdatedKinds => {\n if (!isOutdatedKind(value)) {\n throw error('Expected a valid outdated kind', {\n found: value,\n validOptions: Array.from(kinds),\n })\n }\n return value\n}\n\n/**\n * Fetches the available versions of a package from the npm registry.\n */\nexport const retrieveRemoteVersions = async (\n node: NodeLike,\n specOptions: SpecOptions,\n): Promise<string[]> => {\n const spec = hydrate(node.id, String(node.name), specOptions)\n if (!spec.registry || !node.name) {\n return []\n }\n\n const url = new URL(spec.registry)\n url.pathname = `/${node.name}`\n\n try {\n const response = await fetch(String(url), {\n headers: {\n Accept: 'application/vnd.npm.install-v1+json',\n },\n })\n if (!response.ok) {\n // eslint-disable-next-line no-console\n console.warn(\n error('Failed to fetch packument', {\n name: String(node.name),\n spec,\n response,\n }),\n )\n return []\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const packument: Packument = await response.json()\n return Object.keys(packument.versions).sort(compare)\n } catch (e) {\n const err = e as Error\n // eslint-disable-next-line no-console\n console.warn(\n error('Could not retrieve registry versions', {\n name: String(node.name),\n spec,\n cause: err,\n }),\n )\n return []\n }\n}\n\n/**\n * Retrieves what kind of check the :outdated selector should perform.\n */\nexport const parseInternals = (\n nodes: PostcssNode[],\n): OutdatedInternals => {\n let kind: OutdatedKinds = 'any'\n\n if (isStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])) {\n kind = asOutdatedKind(\n removeQuotes(\n asStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])\n .value,\n ),\n )\n } else if (\n isTagNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])\n ) {\n kind = asOutdatedKind(\n asTagNode(asPostcssNodeWithChildren(nodes[0]).nodes[0]).value,\n )\n }\n\n return { kind }\n}\n\n/**\n * Filter nodes by queueing up for removal those that are not outdated.\n */\nexport const queueNode = async (\n state: ParserState,\n node: NodeLike,\n kind: OutdatedKinds,\n): Promise<NodeLike | undefined> => {\n if (!node.name || !node.version) {\n return node\n }\n\n const nodeVersion: string = node.version\n const versions = await retrieveRemoteVersions(\n node,\n state.specOptions,\n )\n\n const greaterVersions = versions.filter((version: string) =>\n gt(version, nodeVersion),\n )\n\n // if there are no greater versions, then the node is not outdated\n if (!greaterVersions.length) {\n return node\n }\n\n const checkKind = new Map<OutdatedKinds, SemverTypeExtraction>([\n ['major', major],\n ['minor', minor],\n ['patch', patch],\n ])\n\n switch (kind) {\n case 'any':\n return\n case 'major':\n case 'minor':\n case 'patch': {\n return (\n greaterVersions.some((version: string) => {\n const va = checkKind.get(kind)?.(version)\n const vb = checkKind.get(kind)?.(nodeVersion)\n /* c8 ignore next - impossible but typescript doesn't know */\n if (va === undefined || vb === undefined) return false\n return va > vb\n })\n ) ?\n undefined\n : node\n }\n // the node should be part of the result as long as it has at least\n // one parent node that has a spec definition that satisfies one\n // of the available remove versions\n case 'in-range': {\n for (const edge of node.edgesIn) {\n // if the edge is not part of the partial results, skip it\n /* c8 ignore next */\n if (!state.partial.edges.has(edge)) continue\n\n if (\n greaterVersions.some(\n version =>\n edge.spec.final.range &&\n satisfies(version, edge.spec.final.range),\n )\n ) {\n return\n }\n }\n return node\n }\n // the node is part of the result as long as none of its parents has\n // a spec definition that satisfies one of the available remote versions\n case 'out-of-range': {\n for (const edge of node.edgesIn) {\n // if the edge is not part of the partial results, skip it\n /* c8 ignore next */\n if (!state.partial.edges.has(edge)) continue\n\n if (\n greaterVersions.some(\n version =>\n edge.spec.final.range &&\n satisfies(version, edge.spec.final.range),\n )\n ) {\n return node\n }\n }\n return\n }\n }\n}\n\n/**\n * Filters out nodes that are not outdated.\n *\n * The :outdated() pseudo selector supports one `type` argument,\n * possible values are the following:\n *\n * - `any`: Selects all nodes that have a greater version available.\n * - `major`: Selects all nodes that have a greater major version available.\n * - `minor`: Selects all nodes that have a greater minor version available.\n * - `patch`: Selects all nodes that have a greater patch version available.\n * - `in-range`: Selects all nodes that have a parent node with a spec definition\n * that satisfies one of the available remote versions.\n * - `out-of-range`: Selects all nodes that have a parent node with a spec definition\n * that does not satisfy any of the available remote versions.\n */\nexport const outdated = async (state: ParserState) => {\n let internals\n try {\n internals = parseInternals(\n asPostcssNodeWithChildren(state.current).nodes,\n )\n } catch (err) {\n throw error('Failed to parse :outdated selector', {\n cause: err,\n })\n }\n\n const { kind } = internals\n const queue = []\n\n for (const node of state.partial.nodes) {\n // filter out nodes that are always ignored by the outdated selector\n if (\n node.mainImporter ||\n node.manifest?.private ||\n splitDepID(node.id)[0] !== 'registry'\n ) {\n removeNode(state, node)\n continue\n }\n\n // fetchs outdated info and performs checks to define\n // whether or not a node should be filtered out\n queue.push(queueNode(state, node, kind))\n }\n\n // nodes queued for removal are then finally removed\n const removeNodeQueue = await Promise.all(queue)\n for (const node of removeNodeQueue) {\n if (node) {\n removeNode(state, node)\n }\n }\n\n return state\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import type { Version } from '@vltpkg/semver';
2
+ import type { AttrInternals } from './attr.ts';
3
+ import type { ParserState, PostcssNode } from '../types.ts';
4
+ export type SemverInternals = {
5
+ semverValue: string;
6
+ semverFunction: SemverComparatorFn;
7
+ compareAttribute: SemverCompareAttribute;
8
+ };
9
+ export type SemverFunctionNames = 'satisfies' | 'gt' | 'gte' | 'lt' | 'lte' | 'eq' | 'neq';
10
+ export type SemverComparatorFn = (version: Version | string, range: string) => boolean;
11
+ export type SemverCompareAttribute = Pick<AttrInternals, 'attribute' | 'properties'> | undefined;
12
+ export declare const isSemverFunctionName: (name: string) => name is SemverFunctionNames;
13
+ export declare const asSemverFunctionName: (name: string) => SemverFunctionNames;
14
+ export declare const parseInternals: (nodes: PostcssNode[], loose: boolean) => SemverInternals;
15
+ export declare const semverParser: (state: ParserState) => Promise<ParserState>;
16
+ //# sourceMappingURL=semver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semver.d.ts","sourceRoot":"","sources":["../../../src/pseudo/semver.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAG7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAc9C,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAG3D,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,kBAAkB,CAAA;IAClC,gBAAgB,EAAE,sBAAsB,CAAA;CACzC,CAAA;AAED,MAAM,MAAM,mBAAmB,GAC3B,WAAW,GACX,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,CAAA;AACT,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,OAAO,GAAG,MAAM,EACzB,KAAK,EAAE,MAAM,KACV,OAAO,CAAA;AACZ,MAAM,MAAM,sBAAsB,GAC9B,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,YAAY,CAAC,GAC/C,SAAS,CAAA;AAWb,eAAO,MAAM,oBAAoB,SACzB,MAAM,KACX,IAAI,IAAI,mBAAoD,CAAA;AAE/D,eAAO,MAAM,oBAAoB,SACzB,MAAM,KACX,mBAQF,CAAA;AAmBD,eAAO,MAAM,cAAc,UAClB,WAAW,EAAE,SACb,OAAO,KACb,eA2GF,CAAA;AAED,eAAO,MAAM,YAAY,UAAiB,WAAW,yBAyDpD,CAAA"}
@@ -0,0 +1,180 @@
1
+ import { satisfies, gt, gte, lt, lte, eq, neq, parse, parseRange, } from '@vltpkg/semver';
2
+ import { error } from '@vltpkg/error-cause';
3
+ import { parseInternals as parseAttrInternals } from "./attr.js";
4
+ import { getManifestPropertyValues } from "../attribute.js";
5
+ import { asAttributeNode, asPostcssNodeWithChildren, asPseudoNode, asStringNode, asTagNode, isAttributeNode, isClassNode, isCombinatorNode, isPseudoNode, isStringNode, } from "../types.js";
6
+ import { removeNode, removeQuotes } from "./helpers.js";
7
+ const semverFunctionNames = new Set([
8
+ 'satisfies',
9
+ 'gt',
10
+ 'gte',
11
+ 'lt',
12
+ 'lte',
13
+ 'eq',
14
+ 'neq',
15
+ ]);
16
+ export const isSemverFunctionName = (name) => semverFunctionNames.has(name);
17
+ export const asSemverFunctionName = (name) => {
18
+ if (!isSemverFunctionName(name)) {
19
+ throw error('Invalid semver function name', {
20
+ found: name,
21
+ validOptions: Array.from(semverFunctionNames),
22
+ });
23
+ }
24
+ return name;
25
+ };
26
+ const semverFunctions = new Map([
27
+ ['satisfies', satisfies],
28
+ ['gt', gt],
29
+ ['gte', gte],
30
+ ['lt', lt],
31
+ ['lte', lte],
32
+ ['eq', eq],
33
+ ['neq', neq],
34
+ ]);
35
+ // list a few css combinators that should never have
36
+ // spaces around when parsing as a semver range
37
+ const unspacedCombinators = new Set([' ', '+']);
38
+ export const parseInternals = (nodes, loose) => {
39
+ // tries to parse the first param as a string node, otherwise defaults
40
+ // to reading all postcss nodes as just strings, since it just means
41
+ // the value was defined as an unquoted string
42
+ let semverValue;
43
+ try {
44
+ semverValue = removeQuotes(asStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])
45
+ .value);
46
+ }
47
+ catch (e) {
48
+ const err = e;
49
+ if (err.message === 'Mismatching query node') {
50
+ semverValue = '';
51
+ for (const node of asPostcssNodeWithChildren(nodes[0]).nodes) {
52
+ if (isClassNode(node)) {
53
+ semverValue += '.';
54
+ }
55
+ else if (isCombinatorNode(node) &&
56
+ !unspacedCombinators.has(node.value)) {
57
+ semverValue += ' ';
58
+ }
59
+ if (node.value) {
60
+ semverValue += node.value;
61
+ }
62
+ }
63
+ }
64
+ else {
65
+ throw err;
66
+ }
67
+ }
68
+ // second param is the function name
69
+ let fnName = 'satisfies';
70
+ try {
71
+ // if there is a second node defined, try to parse it as a string node
72
+ // first and if that fails, then parse it as a tag node which just means
73
+ // it was defined as an unquoted string
74
+ if (nodes[1]) {
75
+ try {
76
+ fnName = asSemverFunctionName(removeQuotes(asStringNode(asPostcssNodeWithChildren(nodes[1]).nodes[0])
77
+ .value));
78
+ }
79
+ catch (e) {
80
+ const err = e;
81
+ if (err.message === 'Mismatching query node') {
82
+ fnName = asSemverFunctionName(asTagNode(asPostcssNodeWithChildren(nodes[1]).nodes[0])
83
+ .value);
84
+ }
85
+ else {
86
+ throw err;
87
+ }
88
+ }
89
+ }
90
+ }
91
+ catch (e) {
92
+ // allow invalid semver function names in loose mode, defaults to satisfies
93
+ if (!loose) {
94
+ throw e;
95
+ }
96
+ }
97
+ const semverFunction = semverFunctions.get(fnName);
98
+ // the following should never happen as long as the semver function names
99
+ // type and Set are correctly mirroring each other values
100
+ /* c8 ignore start */
101
+ if (!semverFunction) {
102
+ throw error('Invalid semver function name', {
103
+ found: fnName,
104
+ validOptions: Array.from(semverFunctions.keys()),
105
+ });
106
+ }
107
+ /* c8 ignore stop */
108
+ // optional third param is the compare value
109
+ let compareAttribute;
110
+ if (nodes[2]) {
111
+ const parentNode = asPostcssNodeWithChildren(nodes[2]);
112
+ const currNode = parentNode.nodes[0];
113
+ if (isAttributeNode(currNode)) {
114
+ const { attribute } = asAttributeNode(currNode);
115
+ compareAttribute = {
116
+ attribute,
117
+ properties: [attribute],
118
+ };
119
+ }
120
+ else if (isPseudoNode(currNode)) {
121
+ compareAttribute = parseAttrInternals(asPseudoNode(currNode).nodes);
122
+ }
123
+ else if (isStringNode(currNode)) {
124
+ const attribute = removeQuotes(asStringNode(currNode).value);
125
+ compareAttribute = {
126
+ attribute,
127
+ properties: [attribute],
128
+ };
129
+ }
130
+ }
131
+ return {
132
+ semverValue,
133
+ semverFunction,
134
+ compareAttribute,
135
+ };
136
+ };
137
+ export const semverParser = async (state) => {
138
+ let internals;
139
+ try {
140
+ internals = parseInternals(asPostcssNodeWithChildren(state.current).nodes, !!state.loose);
141
+ }
142
+ catch (err) {
143
+ throw error('Failed to parse :semver selector', {
144
+ cause: err,
145
+ });
146
+ }
147
+ const { semverValue, semverFunction, compareAttribute } = internals;
148
+ for (const node of state.partial.nodes) {
149
+ if (compareAttribute) {
150
+ const compareValues = getManifestPropertyValues(node, compareAttribute.properties, compareAttribute.attribute);
151
+ // if the provided semver value is a fixed semver version and the
152
+ // compare attribute is resolving to a range value, then we flip the
153
+ // order of comparison, in case it's a "satisfies" function check
154
+ const compareValue = compareValues?.[0];
155
+ const semverValueVersion = parse(semverValue);
156
+ const compareValueRange = compareValue && parseRange(compareValue);
157
+ if (semverFunction === satisfies &&
158
+ semverValueVersion &&
159
+ compareValueRange) {
160
+ if (!satisfies(semverValueVersion, compareValueRange)) {
161
+ removeNode(state, node);
162
+ }
163
+ // otherwise just compares the read attribute to the semver value
164
+ }
165
+ else if (!compareValue ||
166
+ !semverFunction(compareValue, semverValue)) {
167
+ removeNode(state, node);
168
+ }
169
+ }
170
+ else {
171
+ const manifestVersion = node.manifest?.version;
172
+ if (!manifestVersion ||
173
+ !semverFunction(manifestVersion, semverValue)) {
174
+ removeNode(state, node);
175
+ }
176
+ }
177
+ }
178
+ return state;
179
+ };
180
+ //# sourceMappingURL=semver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semver.js","sourceRoot":"","sources":["../../../src/pseudo/semver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,EAAE,EACF,GAAG,EACH,EAAE,EACF,GAAG,EACH,EAAE,EACF,GAAG,EACH,KAAK,EACL,UAAU,GACX,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,cAAc,IAAI,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAEhE,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,YAAY,GACb,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAwBvD,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,WAAW;IACX,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,KAAK;CACN,CAAC,CAAA;AACF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,IAAY,EACiB,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AAE/D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,IAAY,EACS,EAAE;IACvB,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,KAAK,CAAC,8BAA8B,EAAE;YAC1C,KAAK,EAAE,IAAI;YACX,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC;SAC9C,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,IAAI,GAAG,CAG7B;IACA,CAAC,WAAW,EAAE,SAAS,CAAC;IACxB,CAAC,IAAI,EAAE,EAAE,CAAC;IACV,CAAC,KAAK,EAAE,GAAG,CAAC;IACZ,CAAC,IAAI,EAAE,EAAE,CAAC;IACV,CAAC,KAAK,EAAE,GAAG,CAAC;IACZ,CAAC,IAAI,EAAE,EAAE,CAAC;IACV,CAAC,KAAK,EAAE,GAAG,CAAC;CACb,CAAC,CAAA;AAEF,oDAAoD;AACpD,+CAA+C;AAC/C,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AAEvD,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,KAAoB,EACpB,KAAc,EACG,EAAE;IACnB,sEAAsE;IACtE,oEAAoE;IACpE,8CAA8C;IAC9C,IAAI,WAAW,CAAA;IACf,IAAI,CAAC;QACH,WAAW,GAAG,YAAY,CACxB,YAAY,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;aACvD,KAAK,CACT,CAAA;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAU,CAAA;QACtB,IAAI,GAAG,CAAC,OAAO,KAAK,wBAAwB,EAAE,CAAC;YAC7C,WAAW,GAAG,EAAE,CAAA;YAChB,KAAK,MAAM,IAAI,IAAI,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;gBAC7D,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtB,WAAW,IAAI,GAAG,CAAA;gBACpB,CAAC;qBAAM,IACL,gBAAgB,CAAC,IAAI,CAAC;oBACtB,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EACpC,CAAC;oBACD,WAAW,IAAI,GAAG,CAAA;gBACpB,CAAC;gBAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACf,WAAW,IAAI,IAAI,CAAC,KAAK,CAAA;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,IAAI,MAAM,GAAwB,WAAW,CAAA;IAC7C,IAAI,CAAC;QACH,sEAAsE;QACtE,wEAAwE;QACxE,uCAAuC;QACvC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,GAAG,oBAAoB,CAC3B,YAAY,CACV,YAAY,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;qBACvD,KAAK,CACT,CACF,CAAA;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,GAAG,GAAG,CAAU,CAAA;gBACtB,IAAI,GAAG,CAAC,OAAO,KAAK,wBAAwB,EAAE,CAAC;oBAC7C,MAAM,GAAG,oBAAoB,CAC3B,SAAS,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;yBACpD,KAAK,CACT,CAAA;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,CAAA;gBACX,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,2EAA2E;QAC3E,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,CAAA;QACT,CAAC;IACH,CAAC;IAED,MAAM,cAAc,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAClD,yEAAyE;IACzE,yDAAyD;IACzD,qBAAqB;IACrB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,KAAK,CAAC,8BAA8B,EAAE;YAC1C,KAAK,EAAE,MAAM;YACb,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;SACjD,CAAC,CAAA;IACJ,CAAC;IACD,oBAAoB;IAEpB,4CAA4C;IAC5C,IAAI,gBAAwC,CAAA;IAC5C,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QACtD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACpC,IAAI,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAA;YAC/C,gBAAgB,GAAG;gBACjB,SAAS;gBACT,UAAU,EAAE,CAAC,SAAS,CAAC;aACxB,CAAA;QACH,CAAC;aAAM,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,gBAAgB,GAAG,kBAAkB,CACnC,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,CAC7B,CAAA;QACH,CAAC;aAAM,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAA;YAC5D,gBAAgB,GAAG;gBACjB,SAAS;gBACT,UAAU,EAAE,CAAC,SAAS,CAAC;aACxB,CAAA;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,WAAW;QACX,cAAc;QACd,gBAAgB;KACjB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,KAAkB,EAAE,EAAE;IACvD,IAAI,SAAS,CAAA;IACb,IAAI,CAAC;QACH,SAAS,GAAG,cAAc,CACxB,yBAAyB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAC9C,CAAC,CAAC,KAAK,CAAC,KAAK,CACd,CAAA;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,CAAC,kCAAkC,EAAE;YAC9C,KAAK,EAAE,GAAG;SACX,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,GAAG,SAAS,CAAA;IAEnE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvC,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,aAAa,GAAG,yBAAyB,CAC7C,IAAI,EACJ,gBAAgB,CAAC,UAAU,EAC3B,gBAAgB,CAAC,SAAS,CAC3B,CAAA;YAED,iEAAiE;YACjE,oEAAoE;YACpE,iEAAiE;YACjE,MAAM,YAAY,GAAG,aAAa,EAAE,CAAC,CAAC,CAAC,CAAA;YACvC,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,CAAC,CAAA;YAC7C,MAAM,iBAAiB,GACrB,YAAY,IAAI,UAAU,CAAC,YAAY,CAAC,CAAA;YAC1C,IACE,cAAc,KAAK,SAAS;gBAC5B,kBAAkB;gBAClB,iBAAiB,EACjB,CAAC;gBACD,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,EAAE,CAAC;oBACtD,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;gBACzB,CAAC;gBACD,iEAAiE;YACnE,CAAC;iBAAM,IACL,CAAC,YAAY;gBACb,CAAC,cAAc,CAAC,YAAY,EAAE,WAAW,CAAC,EAC1C,CAAC;gBACD,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;YACzB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAA;YAC9C,IACE,CAAC,eAAe;gBAChB,CAAC,cAAc,CAAC,eAAe,EAAE,WAAW,CAAC,EAC7C,CAAC;gBACD,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA","sourcesContent":["import {\n satisfies,\n gt,\n gte,\n lt,\n lte,\n eq,\n neq,\n parse,\n parseRange,\n} from '@vltpkg/semver'\nimport type { Version } from '@vltpkg/semver'\nimport { error } from '@vltpkg/error-cause'\nimport { parseInternals as parseAttrInternals } from './attr.ts'\nimport type { AttrInternals } from './attr.ts'\nimport { getManifestPropertyValues } from '../attribute.ts'\nimport {\n asAttributeNode,\n asPostcssNodeWithChildren,\n asPseudoNode,\n asStringNode,\n asTagNode,\n isAttributeNode,\n isClassNode,\n isCombinatorNode,\n isPseudoNode,\n isStringNode,\n} from '../types.ts'\nimport type { ParserState, PostcssNode } from '../types.ts'\nimport { removeNode, removeQuotes } from './helpers.ts'\n\nexport type SemverInternals = {\n semverValue: string\n semverFunction: SemverComparatorFn\n compareAttribute: SemverCompareAttribute\n}\n\nexport type SemverFunctionNames =\n | 'satisfies'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'eq'\n | 'neq'\nexport type SemverComparatorFn = (\n version: Version | string,\n range: string,\n) => boolean\nexport type SemverCompareAttribute =\n | Pick<AttrInternals, 'attribute' | 'properties'>\n | undefined\n\nconst semverFunctionNames = new Set([\n 'satisfies',\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'eq',\n 'neq',\n])\nexport const isSemverFunctionName = (\n name: string,\n): name is SemverFunctionNames => semverFunctionNames.has(name)\n\nexport const asSemverFunctionName = (\n name: string,\n): SemverFunctionNames => {\n if (!isSemverFunctionName(name)) {\n throw error('Invalid semver function name', {\n found: name,\n validOptions: Array.from(semverFunctionNames),\n })\n }\n return name\n}\n\nconst semverFunctions = new Map<\n SemverFunctionNames,\n SemverComparatorFn\n>([\n ['satisfies', satisfies],\n ['gt', gt],\n ['gte', gte],\n ['lt', lt],\n ['lte', lte],\n ['eq', eq],\n ['neq', neq],\n])\n\n// list a few css combinators that should never have\n// spaces around when parsing as a semver range\nconst unspacedCombinators = new Set<string>([' ', '+'])\n\nexport const parseInternals = (\n nodes: PostcssNode[],\n loose: boolean,\n): SemverInternals => {\n // tries to parse the first param as a string node, otherwise defaults\n // to reading all postcss nodes as just strings, since it just means\n // the value was defined as an unquoted string\n let semverValue\n try {\n semverValue = removeQuotes(\n asStringNode(asPostcssNodeWithChildren(nodes[0]).nodes[0])\n .value,\n )\n } catch (e) {\n const err = e as Error\n if (err.message === 'Mismatching query node') {\n semverValue = ''\n for (const node of asPostcssNodeWithChildren(nodes[0]).nodes) {\n if (isClassNode(node)) {\n semverValue += '.'\n } else if (\n isCombinatorNode(node) &&\n !unspacedCombinators.has(node.value)\n ) {\n semverValue += ' '\n }\n\n if (node.value) {\n semverValue += node.value\n }\n }\n } else {\n throw err\n }\n }\n\n // second param is the function name\n let fnName: SemverFunctionNames = 'satisfies'\n try {\n // if there is a second node defined, try to parse it as a string node\n // first and if that fails, then parse it as a tag node which just means\n // it was defined as an unquoted string\n if (nodes[1]) {\n try {\n fnName = asSemverFunctionName(\n removeQuotes(\n asStringNode(asPostcssNodeWithChildren(nodes[1]).nodes[0])\n .value,\n ),\n )\n } catch (e) {\n const err = e as Error\n if (err.message === 'Mismatching query node') {\n fnName = asSemverFunctionName(\n asTagNode(asPostcssNodeWithChildren(nodes[1]).nodes[0])\n .value,\n )\n } else {\n throw err\n }\n }\n }\n } catch (e) {\n // allow invalid semver function names in loose mode, defaults to satisfies\n if (!loose) {\n throw e\n }\n }\n\n const semverFunction = semverFunctions.get(fnName)\n // the following should never happen as long as the semver function names\n // type and Set are correctly mirroring each other values\n /* c8 ignore start */\n if (!semverFunction) {\n throw error('Invalid semver function name', {\n found: fnName,\n validOptions: Array.from(semverFunctions.keys()),\n })\n }\n /* c8 ignore stop */\n\n // optional third param is the compare value\n let compareAttribute: SemverCompareAttribute\n if (nodes[2]) {\n const parentNode = asPostcssNodeWithChildren(nodes[2])\n const currNode = parentNode.nodes[0]\n if (isAttributeNode(currNode)) {\n const { attribute } = asAttributeNode(currNode)\n compareAttribute = {\n attribute,\n properties: [attribute],\n }\n } else if (isPseudoNode(currNode)) {\n compareAttribute = parseAttrInternals(\n asPseudoNode(currNode).nodes,\n )\n } else if (isStringNode(currNode)) {\n const attribute = removeQuotes(asStringNode(currNode).value)\n compareAttribute = {\n attribute,\n properties: [attribute],\n }\n }\n }\n\n return {\n semverValue,\n semverFunction,\n compareAttribute,\n }\n}\n\nexport const semverParser = async (state: ParserState) => {\n let internals\n try {\n internals = parseInternals(\n asPostcssNodeWithChildren(state.current).nodes,\n !!state.loose,\n )\n } catch (err) {\n throw error('Failed to parse :semver selector', {\n cause: err,\n })\n }\n\n const { semverValue, semverFunction, compareAttribute } = internals\n\n for (const node of state.partial.nodes) {\n if (compareAttribute) {\n const compareValues = getManifestPropertyValues(\n node,\n compareAttribute.properties,\n compareAttribute.attribute,\n )\n\n // if the provided semver value is a fixed semver version and the\n // compare attribute is resolving to a range value, then we flip the\n // order of comparison, in case it's a \"satisfies\" function check\n const compareValue = compareValues?.[0]\n const semverValueVersion = parse(semverValue)\n const compareValueRange =\n compareValue && parseRange(compareValue)\n if (\n semverFunction === satisfies &&\n semverValueVersion &&\n compareValueRange\n ) {\n if (!satisfies(semverValueVersion, compareValueRange)) {\n removeNode(state, node)\n }\n // otherwise just compares the read attribute to the semver value\n } else if (\n !compareValue ||\n !semverFunction(compareValue, semverValue)\n ) {\n removeNode(state, node)\n }\n } else {\n const manifestVersion = node.manifest?.version\n if (\n !manifestVersion ||\n !semverFunction(manifestVersion, semverValue)\n ) {\n removeNode(state, node)\n }\n }\n }\n\n return state\n}\n"]}
@@ -1,11 +1,4 @@
1
- import { type ParserState } from './types.js';
2
- export type AttrInternals = {
3
- attribute: string;
4
- insensitive: boolean;
5
- operator?: string;
6
- value?: string;
7
- properties: string[];
8
- };
1
+ import type { ParserState } from './types.ts';
9
2
  /**
10
3
  * Parsers the `pseudo` node types.
11
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"pseudo.d.ts","sourceRoot":"","sources":["../../src/pseudo.ts"],"names":[],"mappings":"AAQA,OAAO,EAOL,KAAK,WAAW,EAEjB,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,EAAE,CAAA;CACrB,CAAA;AAoYD;;GAEG;AACH,eAAO,MAAM,MAAM,UAAiB,WAAW,yBAe9C,CAAA"}
1
+ {"version":3,"file":"pseudo.d.ts","sourceRoot":"","sources":["../../src/pseudo.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAY,WAAW,EAAE,MAAM,YAAY,CAAA;AA6TvD;;GAEG;AACH,eAAO,MAAM,MAAM,UAAiB,WAAW,yBAiB9C,CAAA"}