-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
_entryPoint.ts
133 lines (112 loc) Β· 4.69 KB
/
_entryPoint.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import {FakeFS, NodeFS, NativePath, PortablePath, VirtualFS, ZipOpenFS} from '@yarnpkg/fslib';
import fs from 'fs';
import Module from 'module';
import path from 'path';
import StringDecoder from 'string_decoder';
import {RuntimeState, PnpApi} from '../types';
import {applyPatch} from './applyPatch';
import {hydrateRuntimeState} from './hydrateRuntimeState';
import {MakeApiOptions, makeApi} from './makeApi';
declare var __non_webpack_module__: NodeModule;
declare var $$SETUP_STATE: (hrs: typeof hydrateRuntimeState, basePath?: NativePath) => RuntimeState;
// We must copy the fs into a local, because otherwise
// 1. we would make the NodeFS instance use the function that we patched (infinite loop)
// 2. Object.create(fs) isn't enough, since it won't prevent the proto from being modified
const localFs: typeof fs = {...fs};
const nodeFs = new NodeFS(localFs);
const defaultRuntimeState = $$SETUP_STATE(hydrateRuntimeState);
const defaultPnpapiResolution = path.resolve(__dirname, __filename);
let defaultFsLayer: FakeFS<PortablePath> = new ZipOpenFS({baseFs: nodeFs});
for (const virtualRoot of defaultRuntimeState.virtualRoots)
defaultFsLayer = new VirtualFS(virtualRoot, {baseFs: defaultFsLayer});
const defaultApi = Object.assign(makeApi(defaultRuntimeState, {
fakeFs: defaultFsLayer,
pnpapiResolution: defaultPnpapiResolution,
}), {
/**
* Can be used to generate a different API than the default one (for example
* to map it on `/` rather than the local directory path, or to use a
* different FS layer than the default one).
*/
makeApi: ({
basePath = undefined,
fakeFs = defaultFsLayer,
pnpapiResolution = defaultPnpapiResolution,
...rest
}: Partial<MakeApiOptions> & {basePath?: NativePath}) => {
const apiRuntimeState = typeof basePath !== `undefined`
? $$SETUP_STATE(hydrateRuntimeState, basePath)
: defaultRuntimeState;
return makeApi(apiRuntimeState, {
fakeFs,
pnpapiResolution,
...rest,
});
},
/**
* Will inject the specified API into the environment, monkey-patching FS. Is
* automatically called when the hook is loaded through `--require`.
*/
setup: (api?: PnpApi) => {
applyPatch(api || defaultApi, {
fakeFs: defaultFsLayer,
});
},
});
// eslint-disable-next-line arca/no-default-export
export default defaultApi;
if (__non_webpack_module__.parent && __non_webpack_module__.parent.id === 'internal/preload') {
defaultApi.setup();
if (__non_webpack_module__.filename) {
// We delete it from the cache in order to support the case where the CLI resolver is invoked from "yarn run"
// It's annoying because it might cause some issues when the file is multiple times in NODE_OPTIONS, but it shouldn't happen anyway.
// @ts-ignore
delete Module._cache[__non_webpack_module__.filename];
}
}
// @ts-ignore
if (process.mainModule === __non_webpack_module__) {
const reportError = (code: string, message: string, data: Object) => {
process.stdout.write(`${JSON.stringify([{code, message, data}, null])}\n`);
};
const reportSuccess = (resolution: string | null) => {
process.stdout.write(`${JSON.stringify([null, resolution])}\n`);
};
const processResolution = (request: string, issuer: string) => {
try {
reportSuccess(defaultApi.resolveRequest(request, issuer));
} catch (error) {
reportError(error.code, error.message, error.data);
}
};
const processRequest = (data: string) => {
try {
const [request, issuer] = JSON.parse(data);
processResolution(request, issuer);
} catch (error) {
reportError(`INVALID_JSON`, error.message, error.data);
}
};
if (process.argv.length > 2) {
if (process.argv.length !== 4) {
process.stderr.write(`Usage: ${process.argv[0]} ${process.argv[1]} <request> <issuer>\n`);
process.exitCode = 64; /* EX_USAGE */
} else {
processResolution(process.argv[2], process.argv[3]);
}
} else {
let buffer = '';
const decoder = new StringDecoder.StringDecoder();
process.stdin.on('data', chunk => {
buffer += decoder.write(chunk);
do {
const index = buffer.indexOf('\n');
if (index === -1)
break;
const line = buffer.slice(0, index);
buffer = buffer.slice(index + 1);
processRequest(line);
} while (true);
});
}
}