@noverax/courier-build 0.0.0-stage → 0.4.0
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/LICENSE +21 -0
- package/README.md +289 -2
- package/lib/config/index.d.ts +420 -0
- package/lib/config/index.js +66 -0
- package/lib/config-file-of-Zkwyi9zf.js +28 -0
- package/lib/config-in-page-message-DLd3f0Jd.js +20 -0
- package/lib/courier-routes-options-BYF7Sfdf.d.cts +13 -0
- package/lib/courier-routes-options-BYF7Sfdf.d.ts +13 -0
- package/lib/engine/worker.d.ts +1 -0
- package/lib/engine/worker.js +551 -0
- package/lib/errno-code-CNx_E80R.js +32 -0
- package/lib/esbuild/index.d.ts +58 -0
- package/lib/esbuild/index.js +191 -0
- package/lib/index-_VUU5N5v.d.ts +134 -0
- package/lib/index.d.ts +101 -0
- package/lib/index.js +4 -0
- package/lib/jest/routes-thread.d.ts +1 -0
- package/lib/jest/routes-thread.js +46 -0
- package/lib/jest/transformer.cjs +121 -0
- package/lib/jest/transformer.d.cts +39 -0
- package/lib/load-config-BeedbpkN.js +1419 -0
- package/lib/metro/index.cjs +25 -0
- package/lib/metro/index.d.cts +55 -0
- package/lib/metro/index.d.ts +67 -0
- package/lib/metro/index.js +105 -0
- package/lib/package-file-CVAKY_Nu.js +39 -0
- package/lib/rollup/index.d.ts +51 -0
- package/lib/rollup/index.js +95 -0
- package/lib/routes-engine-BfwrCuNL.d.ts +117 -0
- package/lib/routes-file-DcpgxYb1.js +206 -0
- package/lib/routes-loader-context-40OKDrQp.d.ts +26 -0
- package/lib/routes-module-code-DO3aII6v.js +402 -0
- package/lib/routes-module-id-CnUjQjYF.js +12 -0
- package/lib/routes-read-error-DQhKIE2F.js +30 -0
- package/lib/routes-rule-CjzX6NS5.js +108 -0
- package/lib/rsbuild/index.d.ts +41 -0
- package/lib/rsbuild/index.js +37 -0
- package/lib/rspack/index.d.ts +3 -0
- package/lib/rspack/index.js +1 -0
- package/lib/shared-engine-CCu7vP_0.js +28 -0
- package/lib/vite/index.d.ts +33 -0
- package/lib/vite/index.js +346 -0
- package/lib/webpack/index.d.ts +4 -0
- package/lib/webpack/index.js +3 -0
- package/lib/webpack/loader.cjs +31 -0
- package/lib/webpack/loader.d.cts +40 -0
- package/lib/webpack/run-routes-loader.d.ts +22 -0
- package/lib/webpack/run-routes-loader.js +103 -0
- package/lib/webpack-B0v9i8lk.js +42 -0
- package/lib/worker-messages-BT2vvNQJ.js +35 -0
- package/package.json +209 -4
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { CourierError } from "@noverax/courier";
|
|
2
|
+
import { Jiti, TransformOptions, TransformResult } from "jiti";
|
|
3
|
+
import { CourierConfig } from "@noverax/courier/config";
|
|
4
|
+
/** The file names a Courier config may have, in the order they are looked for */
|
|
5
|
+
export declare const CONFIG_BASENAMES: ReadonlyArray<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Every path a config is looked for at from a folder, in the order it is
|
|
8
|
+
* looked for: each of {@link CONFIG_BASENAMES} in the folder, then in each
|
|
9
|
+
* folder above it, up to the top of the project — the first folder that
|
|
10
|
+
* holds its repository (`.git`, `.hg`, `.jj`) or is the root of its
|
|
11
|
+
* workspace (`pnpm-workspace.yaml`, or a `package.json` that declares
|
|
12
|
+
* `workspaces`) — or, with no such folder, the root of the file system.
|
|
13
|
+
*
|
|
14
|
+
* @param startDir - The folder to look in first
|
|
15
|
+
* @returns The paths, absolute, whether there or not
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* configCandidates("/repo/apps/web"); // → ["/repo/apps/web/courier.config.ts", …, "/repo/courier.config.cjs"]
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function configCandidates(startDir: string): string[];
|
|
22
|
+
/**
|
|
23
|
+
* A store of jiti transforms: TypeScript and ESM sources compiled to the
|
|
24
|
+
* CommonJS jiti evaluates, reused while the bytes and options that produced
|
|
25
|
+
* them are unchanged.
|
|
26
|
+
*/
|
|
27
|
+
interface TransformCache {
|
|
28
|
+
/**
|
|
29
|
+
* What jiti's transform yields for `options`: the kept code when the store
|
|
30
|
+
* holds a successful transform of the same file from the same bytes and
|
|
31
|
+
* options, and otherwise whatever `compute` returns.
|
|
32
|
+
*
|
|
33
|
+
* @param options - What jiti hands its transform
|
|
34
|
+
* @param compute - jiti's own transform, run on a miss
|
|
35
|
+
* @returns The result of `compute`, or its kept code, byte for byte
|
|
36
|
+
*/
|
|
37
|
+
transform(options: TransformOptions, compute: (options: TransformOptions) => TransformResult): TransformResult;
|
|
38
|
+
}
|
|
39
|
+
/** Where a {@link TransformCache} keeps transforms, and how much in memory. */
|
|
40
|
+
interface TransformCacheOptions {
|
|
41
|
+
/**
|
|
42
|
+
* A directory to keep transforms in across processes, as
|
|
43
|
+
* `findTransformCacheDirectory` finds it. Without one, or with `null`,
|
|
44
|
+
* transforms are kept in memory only.
|
|
45
|
+
*/
|
|
46
|
+
directory?: string | null | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Characters of transformed code kept in memory across all files; the file
|
|
49
|
+
* used least recently is dropped first once they are exceeded. `0` keeps
|
|
50
|
+
* none, for a process that loads each module once. Defaults to 128 Mi
|
|
51
|
+
* characters.
|
|
52
|
+
*/
|
|
53
|
+
maxMemoryChars?: number | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Whether the `directory` is only read: nothing in it is created, written,
|
|
56
|
+
* pruned or marked as used, so a transform computed on a miss stays in
|
|
57
|
+
* this process. For a process that loads, once, what another process has
|
|
58
|
+
* just kept there, as a mock worker loads the modules Studio loaded: its
|
|
59
|
+
* own entries would only duplicate that process's. Defaults to `false`.
|
|
60
|
+
*/
|
|
61
|
+
readOnly?: boolean | undefined;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create a {@link TransformCache} that keeps transforms in memory for the
|
|
65
|
+
* life of the process and, given a `directory`, on disk for the next one.
|
|
66
|
+
*
|
|
67
|
+
* Each file holds one entry per module system — required and imported are
|
|
68
|
+
* transformed differently, and a module reached both ways keeps both. An
|
|
69
|
+
* entry is reused only when the digest of jiti's version, the options and
|
|
70
|
+
* the source matches, so an edited file is transformed again the first time
|
|
71
|
+
* it is loaded.
|
|
72
|
+
*
|
|
73
|
+
* A transform is looked for in memory, then in the directory, where a hit
|
|
74
|
+
* is also kept in memory; only when both miss is it computed, and a success
|
|
75
|
+
* is then kept in both. The directory is shared with every process that
|
|
76
|
+
* names it, and a directory that cannot be read or written only costs
|
|
77
|
+
* transforms; see `createTransformCacheDisk` for what an entry must be to be
|
|
78
|
+
* used. A mock worker, which loads once the modules Studio has just loaded,
|
|
79
|
+
* opens Studio's directory `readOnly` with `maxMemoryChars: 0`: it reads
|
|
80
|
+
* what Studio kept, adds nothing to the directory, and holds nothing in
|
|
81
|
+
* memory past its one load.
|
|
82
|
+
*
|
|
83
|
+
* A failed transform, one whose result carries an `error`, is never kept:
|
|
84
|
+
* babel can fail on bytes it transforms without complaint a moment later,
|
|
85
|
+
* such as a deeply nested module that overflows the stack while babel is
|
|
86
|
+
* still cold. Such a file is transformed again on every load, and every
|
|
87
|
+
* failure reaches jiti with its error, as it does without a cache. A file
|
|
88
|
+
* named by a relative path, or not named, is transformed every time.
|
|
89
|
+
*
|
|
90
|
+
* @param options - The directory (default: none, memory only), the memory
|
|
91
|
+
* bound (default: 128 Mi characters), and whether the directory is only
|
|
92
|
+
* read (default: no)
|
|
93
|
+
* @returns A cache to pass to `createConfigJiti` or `loadCourierConfig`
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* const transformCache = createTransformCache({
|
|
97
|
+
* directory: findTransformCacheDirectory(projectRoot),
|
|
98
|
+
* });
|
|
99
|
+
* const first = await loadCourierConfig({ cwd: projectRoot, transformCache });
|
|
100
|
+
* // Unchanged modules are not transformed again, here or in the next process:
|
|
101
|
+
* const second = await loadCourierConfig({ cwd: projectRoot, transformCache });
|
|
102
|
+
*
|
|
103
|
+
* // A process that loads once what another has just kept:
|
|
104
|
+
* const reader = createTransformCache({ directory, readOnly: true, maxMemoryChars: 0 });
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function createTransformCache({ directory, maxMemoryChars, readOnly }?: TransformCacheOptions): TransformCache;
|
|
108
|
+
/** How a project-file loader resolves imports and transforms modules. */
|
|
109
|
+
interface ConfigJitiOptions {
|
|
110
|
+
/**
|
|
111
|
+
* Whether imports resolve through the project's tsconfig path aliases, as
|
|
112
|
+
* the project's own files expect. Off to load an installed package as it is:
|
|
113
|
+
* an alias of its scope would send its imports to project sources.
|
|
114
|
+
*/
|
|
115
|
+
aliases?: boolean | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Where to reuse each module's transform while its bytes are unchanged.
|
|
118
|
+
* Without one, every module is transformed on every load. Aliases take no
|
|
119
|
+
* part in it: they change where an import resolves, never the code a
|
|
120
|
+
* module's own bytes transform to.
|
|
121
|
+
*/
|
|
122
|
+
transformCache?: TransformCache | undefined;
|
|
123
|
+
/**
|
|
124
|
+
* Told the file of each module the load transforms — the config and every
|
|
125
|
+
* TypeScript or ES module of the project it reaches — so whoever follows
|
|
126
|
+
* the project knows which files its config depends on.
|
|
127
|
+
*/
|
|
128
|
+
onModule?: ((filename: string) => void) | undefined;
|
|
129
|
+
/**
|
|
130
|
+
* Runs each transform the load makes, the first of which loads the
|
|
131
|
+
* transformer itself. A caller noting what the config's code reads runs it
|
|
132
|
+
* unnoted: what the transformer reads is its own, not the config's.
|
|
133
|
+
*/
|
|
134
|
+
runTransform?: (<TResult>(transform: () => TResult) => TResult) | undefined;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* The module loader for Courier's project files — `courier.config.*` and
|
|
138
|
+
* `courier.mocks.*` — with the options both need: the project's tsconfig path
|
|
139
|
+
* aliases, default-export interop, no module cache, and no native import
|
|
140
|
+
* tried before the loader's own.
|
|
141
|
+
*
|
|
142
|
+
* The module cache is off because this is also the reload path: the dev
|
|
143
|
+
* server loads the files again on every edit, and a cached module would hand
|
|
144
|
+
* back the file as it was before the user changed it. Every load therefore
|
|
145
|
+
* reads and evaluates every file again; a `transformCache` only spares the
|
|
146
|
+
* transform of a file whose bytes are unchanged.
|
|
147
|
+
*
|
|
148
|
+
* jiti's native attempt, which imports every module natively before falling
|
|
149
|
+
* back to its own loader, stays off too, whatever `JITI_TRY_NATIVE` says and
|
|
150
|
+
* under Bun, where it defaults to on: a module imported natively is the
|
|
151
|
+
* runtime's first evaluation of it for the life of the process, so an edit to
|
|
152
|
+
* it would never be seen, and the attempt comes before the module cache
|
|
153
|
+
* `evalModule` is handed, so two files evaluated over one cache would each
|
|
154
|
+
* evaluate a module they both import.
|
|
155
|
+
*
|
|
156
|
+
* jiti's own file cache stays off, with or without a `transformCache`:
|
|
157
|
+
* - it writes each entry in place, so concurrent writers can leave an entry
|
|
158
|
+
* torn between two transforms that its check still accepts;
|
|
159
|
+
* - an entry it cannot write makes the whole load throw `EACCES`;
|
|
160
|
+
* - unless the file's own directory has a `node_modules`, it falls back to
|
|
161
|
+
* `os.tmpdir()/jiti`, where another user of the machine can place an entry
|
|
162
|
+
* that is then run;
|
|
163
|
+
* - its key ignores `interopDefault` and the babel options, so a transform
|
|
164
|
+
* made under other options can be handed back;
|
|
165
|
+
* - nothing ever prunes it.
|
|
166
|
+
*
|
|
167
|
+
* jiti is loaded here rather than at the top of a module so a bundler that
|
|
168
|
+
* merely reaches this code does not pull a TypeScript transpiler into its
|
|
169
|
+
* graph; only a process that actually reads such a file pays for it.
|
|
170
|
+
*
|
|
171
|
+
* @param file - Absolute, symlink-resolved path of the file to load; modules
|
|
172
|
+
* and aliases resolve from its directory
|
|
173
|
+
* @param options - Whether to resolve through the project's path aliases
|
|
174
|
+
* (default: yes), and where to reuse transforms (default: nowhere)
|
|
175
|
+
* @returns A jiti instance for that file
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* const transformCache = createTransformCache();
|
|
179
|
+
* const jiti = await createConfigJiti(configFile, { transformCache });
|
|
180
|
+
* const config = await jiti.import(configFile, { default: true });
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
export declare function createConfigJiti(file: string, { aliases, transformCache, onModule, runTransform }?: ConfigJitiOptions): Promise<Jiti>;
|
|
184
|
+
/**
|
|
185
|
+
* Result of a successful `loadCourierConfig` call.
|
|
186
|
+
*
|
|
187
|
+
* `configFile` is the absolute, symlink-resolved path of the file that
|
|
188
|
+
* was loaded — the dev-server side uses it for the `fs.watch` dep tracker;
|
|
189
|
+
* the runtime side uses it only for log/debug output.
|
|
190
|
+
*/
|
|
191
|
+
interface LoadedCourierConfig {
|
|
192
|
+
config: CourierConfig;
|
|
193
|
+
configFile: string;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Options for `loadCourierConfig`.
|
|
197
|
+
*/
|
|
198
|
+
interface LoadCourierConfigOptions {
|
|
199
|
+
/**
|
|
200
|
+
* Starting directory for the config search. Defaults to `process.cwd()`.
|
|
201
|
+
* The dev-server passes the explicit project root; the runtime path
|
|
202
|
+
* passes `process.cwd()` so the walk-up finds configs located at the
|
|
203
|
+
* workspace root from a nested package cwd (common in monorepos).
|
|
204
|
+
*/
|
|
205
|
+
cwd?: string | undefined;
|
|
206
|
+
/**
|
|
207
|
+
* When true, skip the walk-up and require the config file to exist at
|
|
208
|
+
* exactly `cwd`. The dev-server uses this because it was told the
|
|
209
|
+
* project root explicitly and wants to distinguish "no config in root"
|
|
210
|
+
* from "config found higher up" (which would usually mean the user
|
|
211
|
+
* pointed at the wrong directory). The runtime path leaves this false
|
|
212
|
+
* so a nested `cwd` still discovers a root-level config.
|
|
213
|
+
*
|
|
214
|
+
* Defaults to false (walk up).
|
|
215
|
+
*/
|
|
216
|
+
requireAtCwd?: boolean | undefined;
|
|
217
|
+
/**
|
|
218
|
+
* Where to reuse each module's transform while its bytes are unchanged. A
|
|
219
|
+
* caller that keeps one across loads transforms only the modules whose
|
|
220
|
+
* bytes changed; without one, every module is transformed on every load.
|
|
221
|
+
*/
|
|
222
|
+
transformCache?: TransformCache | undefined;
|
|
223
|
+
/** Told the file of each module the load transforms; see `createConfigJiti`. */
|
|
224
|
+
onModule?: ((filename: string) => void) | undefined;
|
|
225
|
+
/**
|
|
226
|
+
* Reuse the transforms kept in the project's `node_modules/.cache`, the
|
|
227
|
+
* ones Studio keeps, and keep there the ones this load makes: a process
|
|
228
|
+
* that loads the config beside Studio — an app that attaches, the MCP
|
|
229
|
+
* server, `courier-server` — transforms only the modules no process has
|
|
230
|
+
* transformed yet. On a project of a thousand endpoints that is hundreds
|
|
231
|
+
* of modules, most of a second. Passed over when `transformCache` is given.
|
|
232
|
+
*/
|
|
233
|
+
projectTransforms?: boolean | undefined;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Walk up from `startDir` looking for a `courier.config.*` file, up to the
|
|
237
|
+
* top of the project: the folder that holds its repository or is the root
|
|
238
|
+
* of its workspace (see {@link configCandidates}). A config found in a folder
|
|
239
|
+
* above `startDir` is taken only when it belongs to this user or to the
|
|
240
|
+
* owner of `startDir`, and no user outside its group may write it: a folder
|
|
241
|
+
* many users share, such as `/tmp`, would otherwise run anyone's config.
|
|
242
|
+
*
|
|
243
|
+
* @param startDir - The directory to look in first
|
|
244
|
+
* @returns The absolute path of the first match, or `null` when no directory
|
|
245
|
+
* up to the top of the project holds one
|
|
246
|
+
* @throws UntrustedConfigError when the nearest config lies above `startDir`
|
|
247
|
+
* and someone else could have put it there
|
|
248
|
+
* @example
|
|
249
|
+
* ```ts
|
|
250
|
+
* findConfigFile("/app/src"); // → "/app/courier.config.ts", or null
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
export declare function findConfigFile(startDir: string): string | null;
|
|
254
|
+
/**
|
|
255
|
+
* Find a config file in `cwd` itself, without walking up.
|
|
256
|
+
*
|
|
257
|
+
* @param cwd - The directory to look in
|
|
258
|
+
* @returns The first of {@link CONFIG_BASENAMES} present there, or `null`
|
|
259
|
+
* @example
|
|
260
|
+
* ```ts
|
|
261
|
+
* findConfigFileAt(process.cwd()); // → "/app/courier.config.ts", or null
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
export declare function findConfigFileAt(cwd: string): string | null;
|
|
265
|
+
/**
|
|
266
|
+
* Find and load a `courier.config.*` file.
|
|
267
|
+
*
|
|
268
|
+
* Returns `null` when no config file exists, so a caller can fall back.
|
|
269
|
+
* Throws when a file was found and loading it failed, reporting what the
|
|
270
|
+
* loader reported — for a TypeScript config, usually an unresolvable import.
|
|
271
|
+
*
|
|
272
|
+
* @param options - Where to look, and where to reuse transforms
|
|
273
|
+
* @returns The config and its canonical path, or `null` when there is no config
|
|
274
|
+
* @example
|
|
275
|
+
* ```ts
|
|
276
|
+
* const loaded = await loadCourierConfig({ cwd: projectRoot, requireAtCwd: true });
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
export declare function loadCourierConfig(options?: LoadCourierConfigOptions): Promise<LoadedCourierConfig | null>;
|
|
280
|
+
/**
|
|
281
|
+
* The transforms kept in a project's `node_modules/.cache` — the ones Studio
|
|
282
|
+
* keeps — for a process that loads the project's modules once: it reuses
|
|
283
|
+
* them, keeps there the ones it makes, and holds none in memory.
|
|
284
|
+
*
|
|
285
|
+
* @param projectRoot - The project's root
|
|
286
|
+
* @returns The cache, or `undefined` when the project has no directory to keep them in
|
|
287
|
+
* @example
|
|
288
|
+
* ```ts
|
|
289
|
+
* await loadCourierConfigFile(file, { transformCache: projectTransformCache(dirname(file)) });
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
export declare function projectTransformCache(projectRoot: string): TransformCache | undefined;
|
|
293
|
+
/** How one config file is loaded: the loader's options, and when its code is about to run. */
|
|
294
|
+
interface LoadConfigFileOptions extends ConfigJitiOptions {
|
|
295
|
+
/**
|
|
296
|
+
* Called once the loader is made, just before the config's code runs. A
|
|
297
|
+
* caller noting what that code reads starts here, so the loader's own
|
|
298
|
+
* start-up is not taken for the config's.
|
|
299
|
+
*/
|
|
300
|
+
beforeRun?: (() => void) | undefined;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Load one config file, found by whatever means the caller chose — the
|
|
304
|
+
* standalone server takes it from `--config`.
|
|
305
|
+
*
|
|
306
|
+
* @param file - Absolute path of an existing config file
|
|
307
|
+
* @param options - How the loader resolves imports and where it reuses
|
|
308
|
+
* transforms, see {@link ConfigJitiOptions}, and what runs before the config
|
|
309
|
+
* @returns The config and the canonical path it was loaded from
|
|
310
|
+
* @throws What the loader reported when the file will not load — for a
|
|
311
|
+
* TypeScript config, usually an unresolvable import
|
|
312
|
+
* @example
|
|
313
|
+
* ```ts
|
|
314
|
+
* const { config } = await loadCourierConfigFile("/app/courier.config.ts", {
|
|
315
|
+
* transformCache: createTransformCache(),
|
|
316
|
+
* });
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
export declare function loadCourierConfigFile(file: string, { beforeRun, ...options }?: LoadConfigFileOptions): Promise<LoadedCourierConfig>;
|
|
320
|
+
/** Path aliases a project declares, ready for both consumers. */
|
|
321
|
+
interface PathAliases {
|
|
322
|
+
/**
|
|
323
|
+
* Prefix → absolute target, in the shape jiti's `alias` option takes.
|
|
324
|
+
* Only the first target of a mapping appears: jiti resolves one path per
|
|
325
|
+
* alias, while `candidatesFor` offers every declared target.
|
|
326
|
+
*/
|
|
327
|
+
readonly loader: Readonly<Record<string, string>>;
|
|
328
|
+
/** Absolute paths `specifier` may denote, in declaration order. */
|
|
329
|
+
candidatesFor(specifier: string): string[];
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Read the path aliases that apply to `projectRoot`.
|
|
333
|
+
*
|
|
334
|
+
* @param projectRoot - Directory holding the project's `tsconfig.json`
|
|
335
|
+
* @returns The aliases, empty when the project declares none
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```ts
|
|
339
|
+
* const aliases = readPathAliases("/app");
|
|
340
|
+
* aliases.candidatesFor("@/lib/sources"); // → ["/app/src/lib/sources"]
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
export declare function readPathAliases(projectRoot: string): PathAliases;
|
|
344
|
+
/**
|
|
345
|
+
* Where a project's transforms are kept across processes:
|
|
346
|
+
* `.cache/courier/transform` in the nearest `node_modules` directory at or
|
|
347
|
+
* above the project root.
|
|
348
|
+
*
|
|
349
|
+
* The nearest one is taken, not the one module resolution would reach: under
|
|
350
|
+
* pnpm that lies inside `.pnpm`, and what keeps the directory safe is the
|
|
351
|
+
* rule below, not where it is. Every file in it holds code that Studio, mock
|
|
352
|
+
* workers and build plugins run, so on POSIX the directory is refused when
|
|
353
|
+
* `node_modules`, `.cache`, `courier` or `transform` — those that exist — is
|
|
354
|
+
* a symbolic link or belongs to another user, and when `courier` or
|
|
355
|
+
* `transform`, which only Studio creates, is writable by its group or
|
|
356
|
+
* others; any of these lets someone else replace or remove entries, or put
|
|
357
|
+
* the directory somewhere they control. `node_modules` and `.cache` may be
|
|
358
|
+
* group-writable, as package managers leave them under a umask of 002:
|
|
359
|
+
* whoever can write `node_modules` can replace any package in it already. On
|
|
360
|
+
* Windows only links and other kinds of file are refused.
|
|
361
|
+
*
|
|
362
|
+
* There is none when no `node_modules` exists, as with Yarn Plug'n'Play, or
|
|
363
|
+
* when `COURIER_TRANSFORM_CACHE` is `0`, `false` or `off` in any case. The
|
|
364
|
+
* system temporary directory, which every user of the machine may write, is
|
|
365
|
+
* never used instead. Why there is none is logged at debug level, once for
|
|
366
|
+
* each root until the reason changes, however often the root is looked up.
|
|
367
|
+
*
|
|
368
|
+
* @param projectRoot - The directory holding `courier.config.*`
|
|
369
|
+
* @param env - The environment to read `COURIER_TRANSFORM_CACHE` from
|
|
370
|
+
* (default: `process.env`)
|
|
371
|
+
* @returns The directory, which may not exist yet, or `null` for none
|
|
372
|
+
* @example
|
|
373
|
+
* ```ts
|
|
374
|
+
* const transformCache = createTransformCache({
|
|
375
|
+
* directory: findTransformCacheDirectory(projectRoot),
|
|
376
|
+
* });
|
|
377
|
+
* ```
|
|
378
|
+
*/
|
|
379
|
+
export declare function findTransformCacheDirectory(projectRoot: string, env?: Readonly<Record<string, string | undefined>>): string | null;
|
|
380
|
+
/**
|
|
381
|
+
* The keys of a courier.config that Courier does not read, at the top and
|
|
382
|
+
* in its `studio`, `server`, `runtime` and `agents` blocks — a misspelt `studo:` say
|
|
383
|
+
* — so a load can name them rather than ignore them in silence.
|
|
384
|
+
*
|
|
385
|
+
* @param config - The config, as its module exported it
|
|
386
|
+
* @returns Each such key, dotted under its block
|
|
387
|
+
* @example
|
|
388
|
+
* ```ts
|
|
389
|
+
* unknownConfigKeys({ sources: {}, studo: {}, server: { prot: 3001 } }); // → ["studo", "server.prot"]
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
export declare function unknownConfigKeys(config: unknown): string[];
|
|
393
|
+
/** Where a config that was not run lies, and the folder it was looked for from. */
|
|
394
|
+
interface UntrustedConfigContext extends Record<string, unknown> {
|
|
395
|
+
/** The config, absolute. */
|
|
396
|
+
configFile: string;
|
|
397
|
+
/** The folder the config was looked for from, below it. */
|
|
398
|
+
folder: string;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* The config nearest a folder lies in a folder above it, and someone else
|
|
402
|
+
* could have put it there: it belongs to another user, or any user may
|
|
403
|
+
* write it. It was not run, as it would run with the rights of whoever
|
|
404
|
+
* builds or serves the project.
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* ```ts
|
|
408
|
+
* throw new UntrustedConfigError("/tmp/courier.config.ts", "/tmp/app", "it belongs to uid 1001");
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
411
|
+
export declare class UntrustedConfigError extends CourierError<"CONFIG_NOT_TRUSTED"> {
|
|
412
|
+
readonly context: UntrustedConfigContext;
|
|
413
|
+
/**
|
|
414
|
+
* @param configFile - The config that was not run, absolute
|
|
415
|
+
* @param folder - The folder it was looked for from
|
|
416
|
+
* @param reason - Why it is not trusted, worded to follow "and"
|
|
417
|
+
*/
|
|
418
|
+
constructor(configFile: string, folder: string, reason: string);
|
|
419
|
+
}
|
|
420
|
+
export type { ConfigJitiOptions, LoadConfigFileOptions, LoadCourierConfigOptions, LoadedCourierConfig, PathAliases, TransformCache, TransformCacheOptions, UntrustedConfigContext };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { n as isRecord } from "../errno-code-CNx_E80R.js";
|
|
2
|
+
import { a as projectTransformCache, c as UntrustedConfigError, d as CONFIG_BASENAMES, f as configCandidates, i as loadCourierConfigFile, l as createConfigJiti, n as findConfigFileAt, o as findTransformCacheDirectory, r as loadCourierConfig, s as createTransformCache, t as findConfigFile, u as readPathAliases } from "../load-config-BeedbpkN.js";
|
|
3
|
+
// src/config/unknown-config-keys.ts
|
|
4
|
+
const TOP_LEVEL = {
|
|
5
|
+
sources: true,
|
|
6
|
+
imports: true,
|
|
7
|
+
studio: true,
|
|
8
|
+
server: true,
|
|
9
|
+
runtime: true,
|
|
10
|
+
agents: true
|
|
11
|
+
};
|
|
12
|
+
const BLOCKS = /* @__PURE__ */ new Map([
|
|
13
|
+
["studio", {
|
|
14
|
+
port: true,
|
|
15
|
+
host: true,
|
|
16
|
+
mockBasePort: true,
|
|
17
|
+
open: true,
|
|
18
|
+
allowedSpecHosts: true,
|
|
19
|
+
routes: true
|
|
20
|
+
}],
|
|
21
|
+
["server", {
|
|
22
|
+
port: true,
|
|
23
|
+
host: true,
|
|
24
|
+
allowedOrigins: true,
|
|
25
|
+
allowedHosts: true,
|
|
26
|
+
maxBodyBytes: true,
|
|
27
|
+
maxUploadBytes: true,
|
|
28
|
+
rateLimit: true,
|
|
29
|
+
browsersOnly: true
|
|
30
|
+
}],
|
|
31
|
+
["runtime", { appOrigin: true }],
|
|
32
|
+
["agents", {
|
|
33
|
+
offer: true,
|
|
34
|
+
allow: true,
|
|
35
|
+
deny: true,
|
|
36
|
+
access: true,
|
|
37
|
+
confirm: true
|
|
38
|
+
}]
|
|
39
|
+
]);
|
|
40
|
+
/**
|
|
41
|
+
* The keys of a courier.config that Courier does not read, at the top and
|
|
42
|
+
* in its `studio`, `server`, `runtime` and `agents` blocks — a misspelt `studo:` say
|
|
43
|
+
* — so a load can name them rather than ignore them in silence.
|
|
44
|
+
*
|
|
45
|
+
* @param config - The config, as its module exported it
|
|
46
|
+
* @returns Each such key, dotted under its block
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* unknownConfigKeys({ sources: {}, studo: {}, server: { prot: 3001 } }); // → ["studo", "server.prot"]
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
function unknownConfigKeys(config) {
|
|
53
|
+
if (!isRecord(config)) return [];
|
|
54
|
+
const unknown = [];
|
|
55
|
+
for (const [key, value] of Object.entries(config)) {
|
|
56
|
+
if (!Object.hasOwn(TOP_LEVEL, key)) {
|
|
57
|
+
unknown.push(key);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const known = BLOCKS.get(key);
|
|
61
|
+
if (!known || !isRecord(value)) continue;
|
|
62
|
+
for (const inner of Object.keys(value)) if (!Object.hasOwn(known, inner)) unknown.push(`${key}.${inner}`);
|
|
63
|
+
}
|
|
64
|
+
return unknown;
|
|
65
|
+
}
|
|
66
|
+
export { CONFIG_BASENAMES, UntrustedConfigError, configCandidates, createConfigJiti, createTransformCache, findConfigFile, findConfigFileAt, findTransformCacheDirectory, loadCourierConfig, loadCourierConfigFile, projectTransformCache, readPathAliases, unknownConfigKeys };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { t as errnoCode } from "./errno-code-CNx_E80R.js";
|
|
2
|
+
import { c as UntrustedConfigError, t as findConfigFile } from "./load-config-BeedbpkN.js";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { realpathSync } from "node:fs";
|
|
5
|
+
// src/util/config-file-of.ts
|
|
6
|
+
/**
|
|
7
|
+
* The config file the routes are read from, as a bundler names a module:
|
|
8
|
+
* its real path. One that is not there yet, or that is not run, gives none
|
|
9
|
+
* here; the engine reports why when the routes are read.
|
|
10
|
+
*
|
|
11
|
+
* @param root - The project's root, where the config is looked for and above
|
|
12
|
+
* @param named - The config, from the root or absolute, when it is not the one found
|
|
13
|
+
* @returns The config file, absolute and real; none when there is no config to read
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* configFileOf("/app"); // "/app/courier.config.ts"
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
function configFileOf(root, named) {
|
|
20
|
+
try {
|
|
21
|
+
const file = named === void 0 ? findConfigFile(root) : resolve(root, named);
|
|
22
|
+
return file === null ? void 0 : realpathSync(file);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
if (error instanceof UntrustedConfigError || errnoCode(error) === "ENOENT") return void 0;
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export { configFileOf as t };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
// src/util/config-in-page-message.ts
|
|
3
|
+
/**
|
|
4
|
+
* Why the project's config cannot be a module of a page, and what to write
|
|
5
|
+
* instead. It holds the server's settings and the definition of every API —
|
|
6
|
+
* their addresses, their middleware, what reads their secrets — and imported
|
|
7
|
+
* as a value it ships all of them to the browser. A page needs its type
|
|
8
|
+
* alone, which an `import type` gives without a byte of it.
|
|
9
|
+
*
|
|
10
|
+
* @param configFile - The project's config
|
|
11
|
+
* @returns The message a build fails with
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* configInPageMessage("/app/courier.config.ts"); // "[courier] courier.config.ts is imported into a page as a value, …"
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function configInPageMessage(configFile) {
|
|
18
|
+
return `[courier] ${basename(configFile)} is imported into a page as a value, which would ship the server's settings and every API's definition to the browser. Import its type alone: write \`import type config from\` where the page writes \`import config from\`.`;
|
|
19
|
+
}
|
|
20
|
+
export { configInPageMessage as t };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options of the routes plugins that need to know only where the config is:
|
|
3
|
+
* those of webpack, Rspack, Rsbuild, esbuild, Rollup and Jest, and of the
|
|
4
|
+
* frameworks built on them.
|
|
5
|
+
*/
|
|
6
|
+
interface CourierRoutesOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The config file, from the project's root or absolute, when it is not
|
|
9
|
+
* the `courier.config.*` in the root or the nearest folder above it.
|
|
10
|
+
*/
|
|
11
|
+
config?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export { CourierRoutesOptions as t };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options of the routes plugins that need to know only where the config is:
|
|
3
|
+
* those of webpack, Rspack, Rsbuild, esbuild, Rollup and Jest, and of the
|
|
4
|
+
* frameworks built on them.
|
|
5
|
+
*/
|
|
6
|
+
interface CourierRoutesOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The config file, from the project's root or absolute, when it is not
|
|
9
|
+
* the `courier.config.*` in the root or the nearest folder above it.
|
|
10
|
+
*/
|
|
11
|
+
config?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export { CourierRoutesOptions as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|