@atls/raijin 0.2.1 → 0.2.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,3 +1,3 @@
1
1
  import type { YarnCommandRunner } from './runner.js';
2
- export declare const createYarnCommandEnvironment: (environment?: NodeJS.ProcessEnv) => NodeJS.ProcessEnv;
2
+ export declare const createYarnCommandEnvironment: (cwd: string, environment?: NodeJS.ProcessEnv) => NodeJS.ProcessEnv;
3
3
  export declare const runYarnCommand: YarnCommandRunner;
@@ -1,14 +1,121 @@
1
1
  import { spawn } from 'node:child_process';
2
+ import { delimiter } from 'node:path';
2
3
  import { RaijinYarnCommandException } from './exceptions/command.js';
3
- export const createYarnCommandEnvironment = (environment = process.env) => {
4
+ const PATH_ENVIRONMENT_NAME = /^path$/i;
5
+ const TEMPORARY_YARN_BIN_PATH = /[\\/]xfs-[^\\/]*(?:[\\/]|$)/;
6
+ const PNP_NODE_OPTION = /(?:^|[\\/])\.pnp\.(?:cjs|loader\.mjs)$/;
7
+ const NODE_OPTIONS_WITH_VALUE = new Set(['--experimental-loader', '--loader', '--require', '-r']);
8
+ const isPnPNodeOptionValue = (value) => PNP_NODE_OPTION.test(value);
9
+ const splitNodeOptions = (nodeOptions) => {
10
+ const tokens = [];
11
+ let raw = '';
12
+ let value = '';
13
+ let quote;
14
+ for (let index = 0; index < nodeOptions.length; index += 1) {
15
+ const char = nodeOptions[index];
16
+ if (quote) {
17
+ raw += char;
18
+ if (char === '\\' && nodeOptions[index + 1] === quote) {
19
+ index += 1;
20
+ raw += nodeOptions[index];
21
+ value += nodeOptions[index];
22
+ continue;
23
+ }
24
+ if (char === quote) {
25
+ quote = undefined;
26
+ continue;
27
+ }
28
+ value += char;
29
+ continue;
30
+ }
31
+ if (char === '"' || char === "'") {
32
+ raw += char;
33
+ quote = char;
34
+ continue;
35
+ }
36
+ if (/\s/.test(char)) {
37
+ if (raw) {
38
+ tokens.push({ raw, value });
39
+ raw = '';
40
+ value = '';
41
+ }
42
+ continue;
43
+ }
44
+ raw += char;
45
+ value += char;
46
+ }
47
+ if (raw) {
48
+ tokens.push({ raw, value });
49
+ }
50
+ return tokens;
51
+ };
52
+ const removePnPNodeOptions = (nodeOptions) => {
53
+ const options = splitNodeOptions(nodeOptions);
54
+ const filtered = [];
55
+ for (let index = 0; index < options.length; index += 1) {
56
+ const option = options[index];
57
+ const [name, value] = option.value.split('=', 2);
58
+ if (value && NODE_OPTIONS_WITH_VALUE.has(name) && isPnPNodeOptionValue(value)) {
59
+ continue;
60
+ }
61
+ if (NODE_OPTIONS_WITH_VALUE.has(option.value)) {
62
+ const next = options.at(index + 1);
63
+ if (next && isPnPNodeOptionValue(next.value)) {
64
+ index += 1;
65
+ continue;
66
+ }
67
+ }
68
+ filtered.push(option.raw);
69
+ }
70
+ return filtered.join(' ');
71
+ };
72
+ const isTemporaryYarnBinPath = (value) => TEMPORARY_YARN_BIN_PATH.test(value);
73
+ const sanitizePathEnvironment = (value) => value
74
+ .split(delimiter)
75
+ .filter((item) => item && !isTemporaryYarnBinPath(item))
76
+ .join(delimiter);
77
+ const setPathEnvironment = (environment) => {
78
+ const pathName = Object.keys(environment).find((name) => PATH_ENVIRONMENT_NAME.test(name));
79
+ if (!pathName) {
80
+ return;
81
+ }
82
+ const pathValue = environment[pathName];
83
+ if (!pathValue) {
84
+ return;
85
+ }
86
+ const sanitizedPathValue = sanitizePathEnvironment(pathValue);
87
+ if (sanitizedPathValue) {
88
+ environment[pathName] = sanitizedPathValue;
89
+ }
90
+ else {
91
+ Reflect.deleteProperty(environment, pathName);
92
+ }
93
+ };
94
+ export const createYarnCommandEnvironment = (cwd, environment = process.env) => {
4
95
  const yarnEnvironment = { ...environment };
96
+ const nodeOptions = yarnEnvironment.NODE_OPTIONS;
97
+ delete yarnEnvironment.BERRY_BIN_FOLDER;
98
+ delete yarnEnvironment.npm_config_user_agent;
99
+ delete yarnEnvironment.npm_execpath;
5
100
  delete yarnEnvironment.YARN_IGNORE_PATH;
101
+ if (nodeOptions) {
102
+ const sanitizedNodeOptions = removePnPNodeOptions(nodeOptions);
103
+ if (sanitizedNodeOptions) {
104
+ yarnEnvironment.NODE_OPTIONS = sanitizedNodeOptions;
105
+ }
106
+ else {
107
+ delete yarnEnvironment.NODE_OPTIONS;
108
+ }
109
+ }
110
+ setPathEnvironment(yarnEnvironment);
111
+ yarnEnvironment.INIT_CWD = cwd;
112
+ yarnEnvironment.PROJECT_CWD = cwd;
6
113
  return yarnEnvironment;
7
114
  };
8
115
  export const runYarnCommand = async (args, cwd) => {
9
116
  const child = spawn('yarn', args, {
10
117
  cwd,
11
- env: createYarnCommandEnvironment(),
118
+ env: createYarnCommandEnvironment(cwd),
12
119
  shell: process.platform === 'win32',
13
120
  stdio: 'inherit',
14
121
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atls/raijin",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "license": "BSD-3-Clause",
5
5
  "type": "module",
6
6
  "exports": {