tungsten 0.2.14 → 0.2.16
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/dist/FrameworkConfig.d.ts +3 -2
- package/dist/FrameworkConfig.d.ts.map +1 -1
- package/dist/_client/cjsHelpers.d.ts +2 -1
- package/dist/_client/cjsHelpers.d.ts.map +1 -1
- package/dist/_client/cjsHelpers.js +23 -11
- package/dist/_client/cjsHelpers.sxyt.d.ts +2 -0
- package/dist/_client/cjsHelpers.sxyt.d.ts.map +1 -0
- package/dist/_client/cjsHelpers.sxyt.js +43 -0
- package/dist/babelPlugins/BabelTransformPackageImports.d.ts.map +1 -1
- package/dist/babelPlugins/BabelTransformPackageImports.js +38 -7
- package/dist/babelPlugins/transformPackageImports/getWebLocationOfPackageFile.js +5 -1
- package/dist/babelPlugins/transformPackageImports/resolveBareImport.d.ts +2 -0
- package/dist/babelPlugins/transformPackageImports/resolveBareImport.d.ts.map +1 -0
- package/dist/babelPlugins/transformPackageImports/resolveBareImport.js +28 -0
- package/dist/babelPlugins/transformPackageImports/resolveBareImport.sxyt.d.ts +2 -0
- package/dist/babelPlugins/transformPackageImports/resolveBareImport.sxyt.d.ts.map +1 -0
- package/dist/babelPlugins/transformPackageImports/resolveBareImport.sxyt.js +104 -0
- package/dist/bin/commands/compile.d.ts.map +1 -1
- package/dist/bin/commands/compile.js +50 -23
- package/dist/bin/commands/compile.sxyt.js +54 -0
- package/dist/build/compileJavascript.d.ts.map +1 -1
- package/dist/build/compileJavascript.js +5 -4
- package/dist/compat/forwardRef.d.ts +9 -0
- package/dist/compat/forwardRef.d.ts.map +1 -0
- package/dist/compat/forwardRef.js +10 -0
- package/dist/compat/index.d.ts +2 -0
- package/dist/compat/index.d.ts.map +1 -0
- package/dist/compat/index.js +1 -0
- package/dist/findProjectDir.d.ts +4 -1
- package/dist/findProjectDir.d.ts.map +1 -1
- package/dist/findProjectDir.js +15 -3
- package/dist/findProjectDir.sxyt.d.ts +2 -0
- package/dist/findProjectDir.sxyt.d.ts.map +1 -0
- package/dist/findProjectDir.sxyt.js +82 -0
- package/dist/frameworkConfigSchema.d.ts +4 -4
- package/dist/frameworkConfigSchema.js +1 -1
- package/dist/getUserConfig.d.ts +2 -2
- package/dist/getUserConfig.d.ts.map +1 -1
- package/dist/getUserConfig.js +3 -3
- package/dist/makeFinalConfig.d.ts +2 -2
- package/dist/makeFinalConfig.d.ts.map +1 -1
- package/dist/makeFinalConfig.js +7 -1
- package/dist/testing/ensureTestEnvLoaded.js +1 -1
- package/package.json +2 -1
|
@@ -21,7 +21,7 @@ export type FrameworkConfigBase = {
|
|
|
21
21
|
envSchemasLocation?: EnvSchemasLocation;
|
|
22
22
|
babelOptions?: BabelParserOptions;
|
|
23
23
|
packageSystem?: 'rewrites' | 'aliases';
|
|
24
|
-
ignoreDirs?: string[];
|
|
24
|
+
ignoreDirs?: string | string[];
|
|
25
25
|
ignorePatterns?: string | string[];
|
|
26
26
|
skipPackageCompilation?: string | string[];
|
|
27
27
|
serverMiddleware?: ServerMiddlewareInfo;
|
|
@@ -57,7 +57,7 @@ export type FrameworkConfigCompleteBase = {
|
|
|
57
57
|
envSchemasLocation: EnvSchemasLocation;
|
|
58
58
|
babelOptions?: BabelParserOptions;
|
|
59
59
|
packageSystem: 'rewrites' | 'aliases';
|
|
60
|
-
ignoreDirs?: string[];
|
|
60
|
+
ignoreDirs?: string | string[];
|
|
61
61
|
ignorePatterns?: string | string[];
|
|
62
62
|
skipPackageCompilation?: string | string[];
|
|
63
63
|
serverMiddleware?: ServerMiddlewareInfo;
|
|
@@ -74,5 +74,6 @@ export type FrameworkConfigCompleteWithoutRootComponent = FrameworkConfigComplet
|
|
|
74
74
|
useRootComponent: false;
|
|
75
75
|
};
|
|
76
76
|
export type FrameworkConfigComplete = FrameworkConfigCompleteWithRootComponent | FrameworkConfigCompleteWithoutRootComponent;
|
|
77
|
+
export type FrameworkConfigOverrides = Pick<FrameworkConfigCompleteBase, 'ignoreDirs' | 'ignorePatterns'>;
|
|
77
78
|
export {};
|
|
78
79
|
//# sourceMappingURL=FrameworkConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrameworkConfig.d.ts","sourceRoot":"","sources":["../src/FrameworkConfig.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,IAAI,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAA;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAInD,KAAK,WAAW,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAC5C,KAAK,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AACtC,KAAK,kBAAkB,GAAG,MAAM,CAAA;AAEhC,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;AAenF,MAAM,MAAM,mBAAmB,GAAG;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IAMpB,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;IACvC,YAAY,CAAC,EAAE,kBAAkB,CAAA;IACjC,aAAa,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;IACtC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"FrameworkConfig.d.ts","sourceRoot":"","sources":["../src/FrameworkConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Module } from '../CjsTypes.js';
|
|
1
2
|
declare global {
|
|
2
3
|
interface Window {
|
|
3
4
|
__tungsten_cjs_import: (location: string) => Promise<{
|
|
@@ -5,5 +6,5 @@ declare global {
|
|
|
5
6
|
}>;
|
|
6
7
|
}
|
|
7
8
|
}
|
|
8
|
-
export
|
|
9
|
+
export declare function loadDeps(deps: string[]): Promise<Record<string, Module>>;
|
|
9
10
|
//# sourceMappingURL=cjsHelpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cjsHelpers.d.ts","sourceRoot":"","sources":["../../src/_client/cjsHelpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cjsHelpers.d.ts","sourceRoot":"","sources":["../../src/_client/cjsHelpers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAa,MAAM,gBAAgB,CAAA;AAkCvD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,qBAAqB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;SAAE,CAAC,CAAA;KAC/E;CACJ;AA6BD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,mCAuC5C"}
|
|
@@ -40,19 +40,32 @@ function pathCombine(baseFile, dest) {
|
|
|
40
40
|
throw new Error(`pathCombine error: unknown dest format, expected a relative import. baseDir: ${baseDir} dest: ${dest}`);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
async function loadDeps(deps) {
|
|
43
|
+
export async function loadDeps(deps) {
|
|
44
44
|
const loaded = {};
|
|
45
45
|
const proms = [];
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
// Every dep is queued at most once. Without this, a circular require() between two
|
|
47
|
+
// converted CJS files (common in packages split over many small files) queues the pair
|
|
48
|
+
// forever: the browser serves the repeat import() from its module cache, so nothing
|
|
49
|
+
// fails or even slows down - the returned promise simply never settles, and every
|
|
50
|
+
// import() waiting on that module graph hangs with it.
|
|
51
|
+
const queued = new Set();
|
|
52
|
+
function queueDeps(deps) {
|
|
53
|
+
if (deps === undefined) return;
|
|
54
|
+
for (const dep of deps) {
|
|
55
|
+
if (queued.has(dep)) continue;
|
|
56
|
+
queued.add(dep);
|
|
57
|
+
if (dep.endsWith('json')) {
|
|
58
|
+
proms.push(fetch(dep).then(res => res.json()).then(json => loaded[dep] = json));
|
|
59
|
+
} else {
|
|
60
|
+
proms.push(import(dep).then(m => {
|
|
61
|
+
loaded[dep] = m.default;
|
|
62
|
+
queueDeps(m.deps);
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
54
65
|
}
|
|
55
|
-
}
|
|
66
|
+
}
|
|
67
|
+
queueDeps(deps);
|
|
68
|
+
// queueDeps() adds to proms as each module arrives with its own deps
|
|
56
69
|
let resolved = 0;
|
|
57
70
|
while (resolved < proms.length) {
|
|
58
71
|
const results = await Promise.all(proms);
|
|
@@ -104,5 +117,4 @@ window.__tungsten_cjs_import = async function __tungsten_cjs_import(location /*
|
|
|
104
117
|
cjsModule(module, module.exports, createRequire(location, loadedDeps, cjsModuleCache));
|
|
105
118
|
return module.exports;
|
|
106
119
|
};
|
|
107
|
-
export {};
|
|
108
120
|
//}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cjsHelpers.sxyt.d.ts","sourceRoot":"","sources":["../../src/_client/cjsHelpers.sxyt.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { describe } from 'sxy-test-runner';
|
|
3
|
+
import { mkdtemp, rm, writeFile } from 'fs/promises';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { pathToFileURL } from 'url';
|
|
7
|
+
// cjsHelpers is browser code - it installs a `process` shim and a window global as soon as
|
|
8
|
+
// it is imported. Stub the window it expects and put node's own process back afterwards.
|
|
9
|
+
const nodeProcess = Reflect.get(globalThis, 'process');
|
|
10
|
+
Reflect.set(globalThis, 'window', {});
|
|
11
|
+
const {
|
|
12
|
+
loadDeps
|
|
13
|
+
} = await import("./cjsHelpers.js");
|
|
14
|
+
Reflect.set(globalThis, 'process', nodeProcess);
|
|
15
|
+
// a converted CJS module exports its factory as the default and its dependencies as `deps`
|
|
16
|
+
function moduleSource(deps) {
|
|
17
|
+
return `export const deps = ${JSON.stringify(deps)}\n` + 'export default function (module) { module.exports = {} }\n';
|
|
18
|
+
}
|
|
19
|
+
describe('_client/cjsHelpers loadDeps()', ({
|
|
20
|
+
it
|
|
21
|
+
}) => {
|
|
22
|
+
it(`loads a dependency cycle instead of hanging`, async () => {
|
|
23
|
+
const dir = await mkdtemp(join(tmpdir(), 'tungsten-load-deps-'));
|
|
24
|
+
try {
|
|
25
|
+
const a = pathToFileURL(join(dir, 'a.js')).href;
|
|
26
|
+
const b = pathToFileURL(join(dir, 'b.js')).href;
|
|
27
|
+
const c = pathToFileURL(join(dir, 'c.js')).href;
|
|
28
|
+
// a <-> b is circular, and both reach c
|
|
29
|
+
await writeFile(join(dir, 'a.js'), moduleSource([b, c]));
|
|
30
|
+
await writeFile(join(dir, 'b.js'), moduleSource([a, c]));
|
|
31
|
+
await writeFile(join(dir, 'c.js'), moduleSource([]));
|
|
32
|
+
const timeout = new Promise(resolve => setTimeout(() => resolve('timed out'), 5000).unref());
|
|
33
|
+
const loaded = await Promise.race([loadDeps([a]), timeout]);
|
|
34
|
+
expect(loaded).not.to.equal('timed out');
|
|
35
|
+
expect(Object.keys(loaded).sort()).to.deep.equal([a, b, c].sort());
|
|
36
|
+
} finally {
|
|
37
|
+
await rm(dir, {
|
|
38
|
+
recursive: true,
|
|
39
|
+
force: true
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BabelTransformPackageImports.d.ts","sourceRoot":"","sources":["../../src/babelPlugins/BabelTransformPackageImports.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAOrD,OAAO,EAGH,QAAQ,EACX,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"BabelTransformPackageImports.d.ts","sourceRoot":"","sources":["../../src/babelPlugins/BabelTransformPackageImports.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,7 @@ import { frameworkDistFolder, packageName as frameworkPackageName, packageName,
|
|
|
27
27
|
import { findProjectDir } from "../findProjectDir.js";
|
|
28
28
|
import { cliError, cliWarn, cliNote, cliInfo, cliNews } from "../cliOutput.js";
|
|
29
29
|
import { isBareImport } from "./isBareImport.js";
|
|
30
|
+
import { resolveBareImport } from "./transformPackageImports/resolveBareImport.js";
|
|
30
31
|
import { TungstenError } from "../TungstenError.js";
|
|
31
32
|
import { throwError } from "../throwError.js";
|
|
32
33
|
//import { copyPackageModulesToPackagesFolder } from '../build/copyPackageModulesToPackagesFolder.js'
|
|
@@ -47,6 +48,9 @@ class UnsupportedCompiledDependencyError extends TungstenError {
|
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
const javascriptFileExtensions = ['.js', '.jsx', '.cjs', '.cjsx', '.mjs', '.mjsx', '.ts', '.tsx', '.cts', '.ctx', '.mts', '.mtsx'];
|
|
51
|
+
function isNonEmptyString(value) {
|
|
52
|
+
return typeof value === 'string' && value !== '';
|
|
53
|
+
}
|
|
50
54
|
function hasJavascriptFileExtension(file) {
|
|
51
55
|
for (const ex of javascriptFileExtensions) {
|
|
52
56
|
if (file.endsWith(ex)) return true;
|
|
@@ -89,7 +93,7 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
89
93
|
try {
|
|
90
94
|
const packageName = location.startsWith('@') ? location.split('/').slice(0, 2).join('/') : location.split('/')[0];
|
|
91
95
|
const resolutionPaths = packageName === 'react' || packageName === 'react-dom' ? [opts.projectDir, sourcePackageDir] : [sourcePackageDir];
|
|
92
|
-
fullLocation = require.resolve(location, {
|
|
96
|
+
fullLocation = resolveBareImport(location, resolutionPaths) ?? require.resolve(location, {
|
|
93
97
|
paths: resolutionPaths
|
|
94
98
|
});
|
|
95
99
|
} catch (e) {
|
|
@@ -175,12 +179,14 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
175
179
|
try {
|
|
176
180
|
const packageName = dep.startsWith('@') ? dep.split('/').slice(0, 2).join('/') : dep.split('/')[0];
|
|
177
181
|
if (packageName === 'react' || packageName === 'react-dom') {
|
|
178
|
-
out.push(require.resolve(dep, {
|
|
182
|
+
out.push(resolveBareImport(dep, [opts.projectDir]) ?? require.resolve(dep, {
|
|
179
183
|
paths: [opts.projectDir]
|
|
180
184
|
}));
|
|
181
185
|
continue;
|
|
182
186
|
}
|
|
183
|
-
|
|
187
|
+
// bare imports resolve the way `import` would first, so that a package
|
|
188
|
+
// shipping both builds is taken as ESM rather than through the CJS route
|
|
189
|
+
const f = (isBareImport(dep) ? resolveBareImport(dep, [dirname(file)]) : undefined) ?? getCjsRequire(file).resolve(dep);
|
|
184
190
|
out.push(f);
|
|
185
191
|
} catch (error) {
|
|
186
192
|
throw new UnsupportedCompiledDependencyError(dep, file, history.length === 0 ? [sourceFilename] : history, {
|
|
@@ -217,7 +223,12 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
217
223
|
if (dir in getPackageDirForDirCache) {
|
|
218
224
|
return getPackageDirForDirCache[dir];
|
|
219
225
|
} else {
|
|
220
|
-
|
|
226
|
+
// requireName - the package identity (and so the output folder) must come from
|
|
227
|
+
// the nearest package.json that actually names a package. Nameless marker
|
|
228
|
+
// package.json files (e.g. zod's v4/core, v4/classic) are not package boundaries.
|
|
229
|
+
return getPackageDirForDirCache[dir] = findProjectDir(dir, {
|
|
230
|
+
requireName: true
|
|
231
|
+
});
|
|
221
232
|
}
|
|
222
233
|
}
|
|
223
234
|
const getPackageDirForFile = function getPackageDirForFile(file) {
|
|
@@ -228,6 +239,22 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
228
239
|
function packageIsEsm(packageJson) {
|
|
229
240
|
return packageJson.type === 'module';
|
|
230
241
|
}
|
|
242
|
+
// The module format is decided by the *nearest* package.json, named or not - nameless
|
|
243
|
+
// marker package.json files legitimately set 'type' for their sub folder.
|
|
244
|
+
const getModuleFormatForDirCache = {};
|
|
245
|
+
function getModuleFormatForDir(dir) {
|
|
246
|
+
const cached = getModuleFormatForDirCache[dir];
|
|
247
|
+
if (cached !== undefined) {
|
|
248
|
+
return cached;
|
|
249
|
+
} else {
|
|
250
|
+
const formatDir = findProjectDir(dir);
|
|
251
|
+
const packageJson = require(join(formatDir, 'package.json'));
|
|
252
|
+
return getModuleFormatForDirCache[dir] = packageIsEsm(packageJson) ? 'esm' : 'non-esm';
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function getModuleFormatForFile(file) {
|
|
256
|
+
return getModuleFormatForDir(dirname(file));
|
|
257
|
+
}
|
|
231
258
|
const importedPackageLocations = {};
|
|
232
259
|
function getPackageInfo(packageDir) {
|
|
233
260
|
//console.log('getPackageInfo', packageDir)
|
|
@@ -239,6 +266,10 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
239
266
|
const packageName = packageJson.name;
|
|
240
267
|
const version = packageJson.version;
|
|
241
268
|
const packageIdentifier = `${packageName}@${version}`;
|
|
269
|
+
const missingFields = [...(isNonEmptyString(packageName) ? [] : ['name']), ...(isNonEmptyString(version) ? [] : ['version'])];
|
|
270
|
+
if (missingFields.length > 0) {
|
|
271
|
+
cliWarn(`BabelTransformPackageImports could not resolve a package identifier for` + `\n${packageDir}` + `\nits package.json has no ${missingFields.map(f => `'${f}'`).join(' and no ')}.` + ` Using \`${packageIdentifier}\`, which may collide with other packages` + ` in the output folder.`);
|
|
272
|
+
}
|
|
242
273
|
const packageType = packageIsEsm(packageJson) ? 'esm' : 'non-esm';
|
|
243
274
|
const cacheLocation = join(packagesCacheLocation, packageIdentifier);
|
|
244
275
|
const finalLocation = join(packagesLocation, packageIdentifier);
|
|
@@ -256,7 +287,7 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
256
287
|
const packageLogItem = packages[packageIdentifier];
|
|
257
288
|
if (packageLogItem !== undefined) {
|
|
258
289
|
if (packageLogItem.packageDir !== packageDir) {
|
|
259
|
-
cliWarn(`BabelTransformPackageImports found the same package in 2 different locations:` + `\n${packageLogItem.packageDir}` + `\nand\n${packageDir}`);
|
|
290
|
+
cliWarn(`BabelTransformPackageImports found the same package \`${packageIdentifier}\`` + ` in 2 different locations:` + `\n${packageLogItem.packageDir}` + `\nand\n${packageDir}`);
|
|
260
291
|
}
|
|
261
292
|
}
|
|
262
293
|
if (!(packageIdentifier in packages)) {
|
|
@@ -398,7 +429,7 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
398
429
|
cacheDest,
|
|
399
430
|
finalDest,
|
|
400
431
|
webLocation,
|
|
401
|
-
type: file.endsWith('.json') ? 'json' : syncFile ? 'cmp-cjs' : file.endsWith('.mjs') ? 'esm' : file.endsWith('.cjs') ? 'cjs' :
|
|
432
|
+
type: file.endsWith('.json') ? 'json' : syncFile ? 'cmp-cjs' : file.endsWith('.mjs') ? 'esm' : file.endsWith('.cjs') ? 'cjs' : getModuleFormatForFile(file),
|
|
402
433
|
packageInfo
|
|
403
434
|
};
|
|
404
435
|
}
|
|
@@ -424,7 +455,7 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
424
455
|
});
|
|
425
456
|
//if (file.endsWith('index.cjs')) console.log('checking type for *index.cjs file:', packageInfo.type)
|
|
426
457
|
if (hasJavascriptFileExtension(file)) {
|
|
427
|
-
if (
|
|
458
|
+
if (getModuleFormatForFile(file) === 'esm' && file.endsWith('.js') || file.endsWith('.mjs')) {
|
|
428
459
|
try {
|
|
429
460
|
const code = await babelFileEsm(file /*, packageInfo*/, nonEsmDependenciesFull);
|
|
430
461
|
//console.log('writing file', cacheDest)
|
|
@@ -6,7 +6,11 @@ function getPackageDirForDir(dir) {
|
|
|
6
6
|
if (dir in getPackageDirForDirCache) {
|
|
7
7
|
return getPackageDirForDirCache[dir];
|
|
8
8
|
} else {
|
|
9
|
-
|
|
9
|
+
// requireName - nameless marker package.json files are not package boundaries
|
|
10
|
+
// as far as package identity goes. See findProjectDir().
|
|
11
|
+
return getPackageDirForDirCache[dir] = findProjectDir(dir, {
|
|
12
|
+
requireName: true
|
|
13
|
+
});
|
|
10
14
|
}
|
|
11
15
|
}
|
|
12
16
|
function getPackageDirForFile(file) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveBareImport.d.ts","sourceRoot":"","sources":["../../../src/babelPlugins/transformPackageImports/resolveBareImport.ts"],"names":[],"mappings":"AAcA,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAgB3F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
3
|
+
import { moduleResolve } from 'import-meta-resolve';
|
|
4
|
+
// The conditions Node itself uses for `import`. Packages that ship both builds (zod, for
|
|
5
|
+
// example, has "import": "./index.js" and "require": "./index.cjs") then give us the ESM
|
|
6
|
+
// entry point, which the browser runs as-is instead of going through the CJS conversion.
|
|
7
|
+
const importConditions = new Set(['node', 'import']);
|
|
8
|
+
// Resolve a bare import the way `import` would, from any of the given directories.
|
|
9
|
+
// Returns undefined when the package cannot be resolved that way, so that the caller can
|
|
10
|
+
// fall back to require.resolve() - packages with no "exports" map, or with an "exports"
|
|
11
|
+
// map that only offers "require", still resolve through the CJS route.
|
|
12
|
+
export function resolveBareImport(specifier, fromDirs) {
|
|
13
|
+
for (const dir of fromDirs) {
|
|
14
|
+
// the base must name a file inside the directory, otherwise the node_modules walk
|
|
15
|
+
// starts at the directory's parent
|
|
16
|
+
const base = pathToFileURL(join(dir, '_'));
|
|
17
|
+
let resolved;
|
|
18
|
+
try {
|
|
19
|
+
resolved = moduleResolve(specifier, base, importConditions);
|
|
20
|
+
} catch {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
// node: and data: URLs are not files we can copy to the browser
|
|
24
|
+
if (resolved.protocol !== 'file:') return undefined;
|
|
25
|
+
return fileURLToPath(resolved);
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveBareImport.sxyt.d.ts","sourceRoot":"","sources":["../../../src/babelPlugins/transformPackageImports/resolveBareImport.sxyt.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { describe } from 'sxy-test-runner';
|
|
3
|
+
import { mkdir, mkdtemp, rm, writeFile } from 'fs/promises';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
import { tmpdir } from 'os';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { resolveBareImport } from "./resolveBareImport.js";
|
|
8
|
+
async function makeFixture() {
|
|
9
|
+
const dir = await mkdtemp(join(tmpdir(), 'tungsten-resolve-bare-import-'));
|
|
10
|
+
const modules = join(dir, 'node_modules');
|
|
11
|
+
const dual = join(modules, 'dual-package');
|
|
12
|
+
await mkdir(dual, {
|
|
13
|
+
recursive: true
|
|
14
|
+
});
|
|
15
|
+
await writeFile(join(dual, 'package.json'), JSON.stringify({
|
|
16
|
+
name: 'dual-package',
|
|
17
|
+
version: '1.0.0',
|
|
18
|
+
exports: {
|
|
19
|
+
'.': {
|
|
20
|
+
import: './index.js',
|
|
21
|
+
require: './index.cjs'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}));
|
|
25
|
+
await writeFile(join(dual, 'index.js'), 'export default 1');
|
|
26
|
+
await writeFile(join(dual, 'index.cjs'), 'module.exports = 1');
|
|
27
|
+
const cjsOnly = join(modules, 'cjs-package');
|
|
28
|
+
await mkdir(cjsOnly, {
|
|
29
|
+
recursive: true
|
|
30
|
+
});
|
|
31
|
+
await writeFile(join(cjsOnly, 'package.json'), JSON.stringify({
|
|
32
|
+
name: 'cjs-package',
|
|
33
|
+
version: '1.0.0',
|
|
34
|
+
main: './main.js'
|
|
35
|
+
}));
|
|
36
|
+
await writeFile(join(cjsOnly, 'main.js'), 'module.exports = 1');
|
|
37
|
+
return {
|
|
38
|
+
dir,
|
|
39
|
+
dual,
|
|
40
|
+
cjsOnly
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
describe('resolveBareImport()', ({
|
|
44
|
+
it
|
|
45
|
+
}) => {
|
|
46
|
+
it(`takes the 'import' condition where require.resolve takes 'require'`, async () => {
|
|
47
|
+
const {
|
|
48
|
+
dir,
|
|
49
|
+
dual
|
|
50
|
+
} = await makeFixture();
|
|
51
|
+
try {
|
|
52
|
+
const require = createRequire(join(dir, '_'));
|
|
53
|
+
expect(require.resolve('dual-package')).to.equal(join(dual, 'index.cjs'));
|
|
54
|
+
expect(resolveBareImport('dual-package', [dir])).to.equal(join(dual, 'index.js'));
|
|
55
|
+
} finally {
|
|
56
|
+
await rm(dir, {
|
|
57
|
+
recursive: true,
|
|
58
|
+
force: true
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
it(`resolves a package that only has a legacy main`, async () => {
|
|
63
|
+
const {
|
|
64
|
+
dir,
|
|
65
|
+
cjsOnly
|
|
66
|
+
} = await makeFixture();
|
|
67
|
+
try {
|
|
68
|
+
expect(resolveBareImport('cjs-package', [dir])).to.equal(join(cjsOnly, 'main.js'));
|
|
69
|
+
} finally {
|
|
70
|
+
await rm(dir, {
|
|
71
|
+
recursive: true,
|
|
72
|
+
force: true
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
it(`returns undefined for a package it cannot resolve, so the caller can fall back`, async () => {
|
|
77
|
+
const {
|
|
78
|
+
dir
|
|
79
|
+
} = await makeFixture();
|
|
80
|
+
try {
|
|
81
|
+
expect(resolveBareImport('not-installed', [dir])).to.equal(undefined);
|
|
82
|
+
} finally {
|
|
83
|
+
await rm(dir, {
|
|
84
|
+
recursive: true,
|
|
85
|
+
force: true
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
it(`tries each of the given directories in turn`, async () => {
|
|
90
|
+
const {
|
|
91
|
+
dir,
|
|
92
|
+
dual
|
|
93
|
+
} = await makeFixture();
|
|
94
|
+
try {
|
|
95
|
+
const missing = join(dir, 'no-such-dir');
|
|
96
|
+
expect(resolveBareImport('dual-package', [missing, dir])).to.equal(join(dual, 'index.js'));
|
|
97
|
+
} finally {
|
|
98
|
+
await rm(dir, {
|
|
99
|
+
recursive: true,
|
|
100
|
+
force: true
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/compile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/compile.ts"],"names":[],"mappings":"AA+QA,OAAO,EAAE,CAAA"}
|
|
@@ -18,38 +18,58 @@ const targetOptions = {
|
|
|
18
18
|
'--public': 'public'
|
|
19
19
|
};
|
|
20
20
|
const args = process.argv.slice(3);
|
|
21
|
-
|
|
22
|
-
const position = args.indexOf(option);
|
|
23
|
-
if (position === -1) return undefined;
|
|
24
|
-
const value = args[position + 1];
|
|
25
|
-
if (value === undefined || value.startsWith('--')) {
|
|
26
|
-
cliError(`${option} requires a path`);
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
29
|
-
return value;
|
|
30
|
-
}
|
|
21
|
+
const usage = 'Usage: tungsten compile [targets] [--all] [--watch] [--no-clean] [--output <dir>]';
|
|
31
22
|
if (args.includes('--help') || args.includes('-h')) {
|
|
32
|
-
cliOut(
|
|
23
|
+
cliOut(usage);
|
|
33
24
|
cliOut('Targets: --js, --css, --client, --assets, --public');
|
|
34
25
|
cliOut('With no target options, all targets are compiled.');
|
|
35
26
|
cliOut('Options: --output <dir>, --ready-file <file>, --quiet');
|
|
27
|
+
cliOut(' --ignore-dirs <dir>, --ignore-patterns <pattern>');
|
|
28
|
+
cliOut(' override the config entries of the same name. Repeat the option to');
|
|
29
|
+
cliOut(' give several values, or pass an empty value to ignore nothing.');
|
|
36
30
|
process.exit(0);
|
|
37
31
|
}
|
|
38
32
|
const commandOptions = new Set(['--all', '--watch', '--no-clean', '--quiet']);
|
|
39
|
-
const valueOptions = new Set(['--output', '--ready-file']);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
const valueOptions = new Set(['--output', '--ready-file', '--ignore-dirs', '--ignore-patterns']);
|
|
34
|
+
// values are collected per option so that the list options can be repeated
|
|
35
|
+
const givenOptionValues = new Map();
|
|
36
|
+
const unknownOptions = [];
|
|
37
|
+
let consumedPosition = -1;
|
|
38
|
+
for (const [position, arg] of args.entries()) {
|
|
39
|
+
if (position === consumedPosition) continue; // already taken as an option value
|
|
40
|
+
if (arg in targetOptions || commandOptions.has(arg)) continue;
|
|
41
|
+
if (valueOptions.has(arg)) {
|
|
42
|
+
const value = args[position + 1];
|
|
43
|
+
if (value === undefined || value.startsWith('--')) {
|
|
44
|
+
cliError(`${arg} requires a value`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const values = givenOptionValues.get(arg);
|
|
48
|
+
if (values === undefined) givenOptionValues.set(arg, [value]);else values.push(value);
|
|
49
|
+
consumedPosition = position + 1;
|
|
50
|
+
} else {
|
|
51
|
+
unknownOptions.push(arg);
|
|
52
|
+
}
|
|
44
53
|
}
|
|
45
|
-
const unknownOptions = args.filter(arg => !(arg in targetOptions) && !commandOptions.has(arg) && !valueOptions.has(arg) && !optionValues.has(arg));
|
|
46
54
|
if (unknownOptions.length > 0) {
|
|
47
55
|
cliError(`Unknown compile option${unknownOptions.length === 1 ? '' : 's'}: ${unknownOptions.join(', ')}`);
|
|
48
|
-
cliOut(
|
|
56
|
+
cliOut(usage);
|
|
49
57
|
process.exit(1);
|
|
50
58
|
}
|
|
59
|
+
function optionValue(option) {
|
|
60
|
+
return givenOptionValues.get(option)?.at(-1);
|
|
61
|
+
}
|
|
62
|
+
// undefined leaves the config entry alone, '' clears it
|
|
63
|
+
function listOptionValue(option) {
|
|
64
|
+
const values = givenOptionValues.get(option);
|
|
65
|
+
if (values === undefined) return undefined;
|
|
66
|
+
const entries = values.filter(value => value !== '');
|
|
67
|
+
return entries.length === 0 ? '' : entries;
|
|
68
|
+
}
|
|
51
69
|
const outputOption = optionValue('--output');
|
|
52
70
|
const readyFileOption = optionValue('--ready-file');
|
|
71
|
+
const ignoreDirsOption = listOptionValue('--ignore-dirs');
|
|
72
|
+
const ignorePatternsOption = listOptionValue('--ignore-patterns');
|
|
53
73
|
const requestedTargets = new Set();
|
|
54
74
|
for (const arg of args) {
|
|
55
75
|
const target = targetOptions[arg];
|
|
@@ -60,7 +80,14 @@ const watch = args.includes('--watch');
|
|
|
60
80
|
const clean = !args.includes('--no-clean');
|
|
61
81
|
const quiet = args.includes('--quiet');
|
|
62
82
|
const projectDir = process.cwd();
|
|
63
|
-
const config = await getUserConfig(
|
|
83
|
+
const config = await getUserConfig({
|
|
84
|
+
...(ignoreDirsOption !== undefined ? {
|
|
85
|
+
ignoreDirs: ignoreDirsOption
|
|
86
|
+
} : {}),
|
|
87
|
+
...(ignorePatternsOption !== undefined ? {
|
|
88
|
+
ignorePatterns: ignorePatternsOption
|
|
89
|
+
} : {})
|
|
90
|
+
});
|
|
64
91
|
const codeLocation = join(projectDir, config.codeDir);
|
|
65
92
|
const relSourceDir = config.sourceDir !== undefined && config.sourceDir !== '' ? config.sourceDir : config.codeDir;
|
|
66
93
|
const sourceLocation = join(projectDir, relSourceDir);
|
|
@@ -117,10 +144,10 @@ if (targets.has('js')) {
|
|
|
117
144
|
onCycleComplete: watch ? async cycle => {
|
|
118
145
|
if (cycle.success) {
|
|
119
146
|
await markReady();
|
|
120
|
-
cliNews(`Compile cycle complete: js${cycle.file ? ` (${cycle.file})` : ''}`);
|
|
147
|
+
cliNews(`Compile cycle complete: js${cycle.file !== undefined ? ` (${cycle.file})` : ''}`);
|
|
121
148
|
} else {
|
|
122
149
|
await clearReadyFile();
|
|
123
|
-
cliError(`Compile cycle failed: js${cycle.file ? ` (${cycle.file})` : ''}`);
|
|
150
|
+
cliError(`Compile cycle failed: js${cycle.file !== undefined ? ` (${cycle.file})` : ''}`);
|
|
124
151
|
}
|
|
125
152
|
} : undefined
|
|
126
153
|
});
|
|
@@ -137,8 +164,8 @@ if (targets.has('client')) {
|
|
|
137
164
|
compilationTasks.push(createClientFiles(config, 'dev', buildLocation));
|
|
138
165
|
}
|
|
139
166
|
if (targets.has('assets')) {
|
|
140
|
-
|
|
141
|
-
|
|
167
|
+
// copyAssets resolves to undefined when there is no assets dir - nothing to skip here
|
|
168
|
+
compilationTasks.push(copyAssets(projectDir, config, buildLocation, watch));
|
|
142
169
|
}
|
|
143
170
|
if (targets.has('public')) {
|
|
144
171
|
compilationTasks.push(copyPublicFiles(projectDir, config, buildLocation, watch));
|
|
@@ -94,6 +94,60 @@ describe('tungsten compile', ({
|
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
});
|
|
97
|
+
it('overrides the ignoreDirs and ignorePatterns config entries from the command line', async () => {
|
|
98
|
+
const projectDir = await mkdtemp(join(tmpdir(), 'tungsten-compile-ignore-test-'));
|
|
99
|
+
const cliLocation = join(findProjectDir(import.meta.url), 'dist', 'bin', 'index.js');
|
|
100
|
+
const sourceDir = join(projectDir, 'src');
|
|
101
|
+
async function compiled(rel) {
|
|
102
|
+
try {
|
|
103
|
+
await readFile(join(projectDir, '.tungsten/test/code', rel), 'utf8');
|
|
104
|
+
return true;
|
|
105
|
+
} catch {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
await mkdir(join(sourceDir, 'server'), {
|
|
111
|
+
recursive: true
|
|
112
|
+
});
|
|
113
|
+
await mkdir(join(sourceDir, 'tests'), {
|
|
114
|
+
recursive: true
|
|
115
|
+
});
|
|
116
|
+
await writeFile(join(projectDir, 'package.json'), '{"type":"module"}');
|
|
117
|
+
await writeFile(join(projectDir, 'tungsten.config.js'), 'export default {' + ' codeDir: "src",' + ' useRootComponent: false,' + ' ignoreDirs: "server",' + ' ignorePatterns: "**/*.domTest.js"' + ' }');
|
|
118
|
+
await writeFile(join(sourceDir, 'entry.js'), 'export const entry = 1');
|
|
119
|
+
await writeFile(join(sourceDir, 'server', 'api.js'), 'export const api = 1');
|
|
120
|
+
await writeFile(join(sourceDir, 'tests', 'unit.js'), 'export const unit = 1');
|
|
121
|
+
await writeFile(join(sourceDir, 'component.domTest.js'), 'export const domTest = 1');
|
|
122
|
+
// the config entries alone - server/ and *.domTest.js are left out
|
|
123
|
+
await execFileAsync(process.execPath, [cliLocation, 'compile', '--js', '--output', '.tungsten/test', '--quiet'], {
|
|
124
|
+
cwd: projectDir
|
|
125
|
+
});
|
|
126
|
+
expect(await compiled('entry.js')).to.equal(true);
|
|
127
|
+
expect(await compiled('server/api.js')).to.equal(false);
|
|
128
|
+
expect(await compiled('component.domTest.js')).to.equal(false);
|
|
129
|
+
// blank values override both entries away, so everything is compiled
|
|
130
|
+
await execFileAsync(process.execPath, [cliLocation, 'compile', '--js', '--output', '.tungsten/test', '--quiet', '--ignore-dirs', '', '--ignore-patterns', ''], {
|
|
131
|
+
cwd: projectDir
|
|
132
|
+
});
|
|
133
|
+
expect(await compiled('server/api.js')).to.equal(true);
|
|
134
|
+
expect(await compiled('component.domTest.js')).to.equal(true);
|
|
135
|
+
// repeating an option replaces the config entry with all of the given values
|
|
136
|
+
await execFileAsync(process.execPath, [cliLocation, 'compile', '--js', '--output', '.tungsten/test', '--quiet', '--ignore-dirs', 'tests', '--ignore-dirs', 'server'], {
|
|
137
|
+
cwd: projectDir
|
|
138
|
+
});
|
|
139
|
+
expect(await compiled('entry.js')).to.equal(true);
|
|
140
|
+
expect(await compiled('tests/unit.js')).to.equal(false);
|
|
141
|
+
expect(await compiled('server/api.js')).to.equal(false);
|
|
142
|
+
// ignorePatterns was not overridden, so it still applies
|
|
143
|
+
expect(await compiled('component.domTest.js')).to.equal(false);
|
|
144
|
+
} finally {
|
|
145
|
+
await rm(projectDir, {
|
|
146
|
+
recursive: true,
|
|
147
|
+
force: true
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
});
|
|
97
151
|
it('skips package compilation for files selected by a JavaScript glob', async () => {
|
|
98
152
|
const projectDir = await mkdtemp(join(tmpdir(), 'tungsten-skip-package-compilation-test-'));
|
|
99
153
|
const cliLocation = join(findProjectDir(import.meta.url), 'dist', 'bin', 'index.js');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compileJavascript.d.ts","sourceRoot":"","sources":["../../src/build/compileJavascript.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAO/B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAetC,KAAK,uBAAuB,GAAG;IAC3B,OAAO,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAA;IAClC,WAAW,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAA;IACtC,aAAa,EAAE,aAAa,CAAA;IAC5B,cAAc,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACnC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,eAAe,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAA;CAC9F,CAAA;AAKD,wBAAsB,iBAAiB,CACnC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,uBAAuB,EACtD,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EACrE,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,UAAO,EAC1E,OAAO,GAAE,wBAA6B,GACvC,OAAO,CAAC,uBAAuB,CAAC,
|
|
1
|
+
{"version":3,"file":"compileJavascript.d.ts","sourceRoot":"","sources":["../../src/build/compileJavascript.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAO/B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAetC,KAAK,uBAAuB,GAAG;IAC3B,OAAO,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAA;IAClC,WAAW,EAAE,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAA;IACtC,aAAa,EAAE,aAAa,CAAA;IAC5B,cAAc,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACnC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,eAAe,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAA;CAC9F,CAAA;AAKD,wBAAsB,iBAAiB,CACnC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,uBAAuB,EACtD,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EACrE,aAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,UAAO,EAC1E,OAAO,GAAE,wBAA6B,GACvC,OAAO,CAAC,uBAAuB,CAAC,CA0TlC"}
|
|
@@ -50,7 +50,7 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
|
|
|
50
50
|
const transformPromises = [];
|
|
51
51
|
const failedFiles = new Set();
|
|
52
52
|
async function transformFile(file) {
|
|
53
|
-
if (
|
|
53
|
+
if (options.quiet !== true) console.log('transforming file', file);
|
|
54
54
|
try {
|
|
55
55
|
let rel = file.slice(codeLocationLength);
|
|
56
56
|
if (rel.endsWith('.jsx')) rel = rel.slice(0, -1);
|
|
@@ -121,10 +121,11 @@ export async function compileJavascript(projectDir, appConfig, codeLocation, sou
|
|
|
121
121
|
const watchGlob = slash(`${codeLocation}/**/*.js{,x}`);
|
|
122
122
|
const ignored = [];
|
|
123
123
|
ignored.push(slash(`${buildLocation}/**`));
|
|
124
|
-
if (appConfig.ignoreDirs) {
|
|
125
|
-
|
|
124
|
+
if (appConfig.ignoreDirs !== undefined && appConfig.ignoreDirs !== '') {
|
|
125
|
+
const ignoreDirs = typeof appConfig.ignoreDirs === 'string' ? [appConfig.ignoreDirs] : appConfig.ignoreDirs;
|
|
126
|
+
ignored.push(...ignoreDirs.map(folder => slash(`${codeLocation}/${folder}/**`)));
|
|
126
127
|
}
|
|
127
|
-
if (appConfig.ignorePatterns) {
|
|
128
|
+
if (appConfig.ignorePatterns !== undefined && appConfig.ignorePatterns !== '') {
|
|
128
129
|
if (Array.isArray(appConfig.ignorePatterns)) {
|
|
129
130
|
for (const pattern of appConfig.ignorePatterns) {
|
|
130
131
|
ignored.push(pattern);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RefObject } from '../../types/jsx/jsx.js';
|
|
2
|
+
import type { ContentNode } from '../ContentNode.js';
|
|
3
|
+
export declare const $forwardRef: unique symbol;
|
|
4
|
+
export type $ForwardRef = typeof $forwardRef;
|
|
5
|
+
export declare function forwardRef<T, P extends {}>(render: (props: P, ref: RefObject<T>) => ContentNode): {
|
|
6
|
+
special: symbol;
|
|
7
|
+
render: (props: P, ref: RefObject<T>) => ContentNode;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=forwardRef.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forwardRef.d.ts","sourceRoot":"","sources":["../../src/compat/forwardRef.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,eAAO,MAAM,WAAW,eAAuB,CAAA;AAC/C,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAA;AAG5C,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,EACtC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,WAAW;;oBAApC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,WAAW;EAQvD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const $forwardRef = Symbol('forwardRef');
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
3
|
+
export function forwardRef(render) {
|
|
4
|
+
// we might need a special ContetNode - ForwardRefNode
|
|
5
|
+
// that maps the ref somehow?
|
|
6
|
+
return {
|
|
7
|
+
special: $forwardRef,
|
|
8
|
+
render
|
|
9
|
+
};
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compat/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { forwardRef } from "./forwardRef.js";
|
package/dist/findProjectDir.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type FindProjectDirOptions = {
|
|
2
|
+
requireName?: boolean;
|
|
3
|
+
};
|
|
4
|
+
export declare function findProjectDir(startLocation: string, options?: FindProjectDirOptions): string;
|
|
2
5
|
//# sourceMappingURL=findProjectDir.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findProjectDir.d.ts","sourceRoot":"","sources":["../src/findProjectDir.ts"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"findProjectDir.d.ts","sourceRoot":"","sources":["../src/findProjectDir.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,qBAAqB,GAAG;IAIhC,WAAW,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,UAkBxF"}
|
package/dist/findProjectDir.js
CHANGED
|
@@ -2,12 +2,24 @@ import { dirname } from 'path';
|
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
3
|
import packageJsonFinder from 'find-package-json';
|
|
4
4
|
import { TungstenError } from "./TungstenError.js";
|
|
5
|
-
export function findProjectDir(startLocation) {
|
|
5
|
+
export function findProjectDir(startLocation, options = {}) {
|
|
6
6
|
if (startLocation.startsWith('file:')) startLocation = fileURLToPath(startLocation);
|
|
7
|
-
const
|
|
8
|
-
|
|
7
|
+
const finder = packageJsonFinder(startLocation);
|
|
8
|
+
let packageJson = finder.next();
|
|
9
|
+
if (options.requireName) {
|
|
10
|
+
while (!packageJson.done && !hasName(packageJson.value)) {
|
|
11
|
+
packageJson = finder.next();
|
|
12
|
+
}
|
|
13
|
+
if (packageJson.done) {
|
|
14
|
+
// couldn't find a named package.json
|
|
15
|
+
throw new TungstenError(`findProjectDir() error - could not find a package.json with a 'name'` + ` in any parent directory of ${startLocation}`);
|
|
16
|
+
}
|
|
17
|
+
} else if (packageJson.done) {
|
|
9
18
|
// couldn't find a package.json
|
|
10
19
|
throw new TungstenError(`findProjectDir() error - could not find the package.json is the project directory`);
|
|
11
20
|
}
|
|
12
21
|
return dirname(packageJson.filename);
|
|
22
|
+
}
|
|
23
|
+
function hasName(packageJson) {
|
|
24
|
+
return typeof packageJson === 'object' && packageJson !== null && 'name' in packageJson && typeof packageJson.name === 'string' && packageJson.name !== '';
|
|
13
25
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findProjectDir.sxyt.d.ts","sourceRoot":"","sources":["../src/findProjectDir.sxyt.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { describe } from 'sxy-test-runner';
|
|
2
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { findProjectDir } from "./findProjectDir.js";
|
|
6
|
+
// Build a fixture that mirrors zod v4 - a named package containing a sub folder with a
|
|
7
|
+
// nameless marker package.json that only sets the module format and local entry points.
|
|
8
|
+
function makeFixture() {
|
|
9
|
+
const root = mkdtempSync(join(tmpdir(), 'tungsten-find-project-dir-'));
|
|
10
|
+
const packageDir = join(root, 'fake-package');
|
|
11
|
+
const markerDir = join(packageDir, 'v4', 'core');
|
|
12
|
+
mkdirSync(markerDir, {
|
|
13
|
+
recursive: true
|
|
14
|
+
});
|
|
15
|
+
writeFileSync(join(packageDir, 'package.json'), JSON.stringify({
|
|
16
|
+
name: 'fake-package',
|
|
17
|
+
version: '1.2.3',
|
|
18
|
+
type: 'module'
|
|
19
|
+
}));
|
|
20
|
+
writeFileSync(join(markerDir, 'package.json'), JSON.stringify({
|
|
21
|
+
type: 'module',
|
|
22
|
+
main: './index.cjs',
|
|
23
|
+
module: './index.js'
|
|
24
|
+
}));
|
|
25
|
+
writeFileSync(join(markerDir, 'index.js'), '');
|
|
26
|
+
return {
|
|
27
|
+
root,
|
|
28
|
+
packageDir,
|
|
29
|
+
markerDir
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
describe('findProjectDir()', ({
|
|
33
|
+
it
|
|
34
|
+
}) => {
|
|
35
|
+
it(`returns the nearest package.json dir, named or not, by default`, () => {
|
|
36
|
+
const {
|
|
37
|
+
root,
|
|
38
|
+
markerDir
|
|
39
|
+
} = makeFixture();
|
|
40
|
+
try {
|
|
41
|
+
findProjectDir(markerDir).should.equal(markerDir);
|
|
42
|
+
} finally {
|
|
43
|
+
rmSync(root, {
|
|
44
|
+
recursive: true,
|
|
45
|
+
force: true
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
it(`skips nameless package.json files when requireName is set`, () => {
|
|
50
|
+
const {
|
|
51
|
+
root,
|
|
52
|
+
packageDir,
|
|
53
|
+
markerDir
|
|
54
|
+
} = makeFixture();
|
|
55
|
+
try {
|
|
56
|
+
findProjectDir(markerDir, {
|
|
57
|
+
requireName: true
|
|
58
|
+
}).should.equal(packageDir);
|
|
59
|
+
} finally {
|
|
60
|
+
rmSync(root, {
|
|
61
|
+
recursive: true,
|
|
62
|
+
force: true
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
it(`returns the named package dir when it is the nearest one`, () => {
|
|
67
|
+
const {
|
|
68
|
+
root,
|
|
69
|
+
packageDir
|
|
70
|
+
} = makeFixture();
|
|
71
|
+
try {
|
|
72
|
+
findProjectDir(packageDir, {
|
|
73
|
+
requireName: true
|
|
74
|
+
}).should.equal(packageDir);
|
|
75
|
+
} finally {
|
|
76
|
+
rmSync(root, {
|
|
77
|
+
recursive: true,
|
|
78
|
+
force: true
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -36,7 +36,7 @@ declare const frameworkConfigWithRootComponentValidator: import("arktype/interna
|
|
|
36
36
|
createImportExpressions?: boolean;
|
|
37
37
|
};
|
|
38
38
|
packageSystem?: "rewrites" | "aliases";
|
|
39
|
-
ignoreDirs?: string[];
|
|
39
|
+
ignoreDirs?: string | string[];
|
|
40
40
|
ignorePatterns?: string | string[];
|
|
41
41
|
skipPackageCompilation?: string | string[];
|
|
42
42
|
serverMiddleware?: [string, string, string];
|
|
@@ -81,7 +81,7 @@ declare const frameworkConfigWithoutRootComponentValidator: import("arktype/inte
|
|
|
81
81
|
createImportExpressions?: boolean;
|
|
82
82
|
};
|
|
83
83
|
packageSystem?: "rewrites" | "aliases";
|
|
84
|
-
ignoreDirs?: string[];
|
|
84
|
+
ignoreDirs?: string | string[];
|
|
85
85
|
ignorePatterns?: string | string[];
|
|
86
86
|
skipPackageCompilation?: string | string[];
|
|
87
87
|
serverMiddleware?: [string, string, string];
|
|
@@ -125,7 +125,7 @@ export declare const frameworkConfigValidator: import("arktype/internal/variants
|
|
|
125
125
|
createImportExpressions?: boolean;
|
|
126
126
|
};
|
|
127
127
|
packageSystem?: "rewrites" | "aliases";
|
|
128
|
-
ignoreDirs?: string[];
|
|
128
|
+
ignoreDirs?: string | string[];
|
|
129
129
|
ignorePatterns?: string | string[];
|
|
130
130
|
skipPackageCompilation?: string | string[];
|
|
131
131
|
serverMiddleware?: [string, string, string];
|
|
@@ -169,7 +169,7 @@ export declare const frameworkConfigValidator: import("arktype/internal/variants
|
|
|
169
169
|
createImportExpressions?: boolean;
|
|
170
170
|
};
|
|
171
171
|
packageSystem?: "rewrites" | "aliases";
|
|
172
|
-
ignoreDirs?: string[];
|
|
172
|
+
ignoreDirs?: string | string[];
|
|
173
173
|
ignorePatterns?: string | string[];
|
|
174
174
|
skipPackageCompilation?: string | string[];
|
|
175
175
|
serverMiddleware?: [string, string, string];
|
|
@@ -44,7 +44,7 @@ const frameworkConfigBaseValidator = arkType({
|
|
|
44
44
|
'envSchemasLocation?': 'string',
|
|
45
45
|
'babelOptions?': babelParserOptionsType,
|
|
46
46
|
'packageSystem?': '"rewrites" | "aliases"',
|
|
47
|
-
'ignoreDirs?': 'string[]',
|
|
47
|
+
'ignoreDirs?': 'string | string[]',
|
|
48
48
|
// rename to ignoreFolders?
|
|
49
49
|
'ignorePatterns?': 'string | string[]',
|
|
50
50
|
'skipPackageCompilation?': 'string | string[]',
|
package/dist/getUserConfig.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { FrameworkConfigComplete } from './FrameworkConfig.js';
|
|
2
|
-
export declare function getUserConfig(volume?: 'silent' | 'noisy'): Promise<FrameworkConfigComplete>;
|
|
1
|
+
import { FrameworkConfigComplete, FrameworkConfigOverrides } from './FrameworkConfig.js';
|
|
2
|
+
export declare function getUserConfig(overrides?: FrameworkConfigOverrides | null, volume?: 'silent' | 'noisy'): Promise<FrameworkConfigComplete>;
|
|
3
3
|
//# sourceMappingURL=getUserConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getUserConfig.d.ts","sourceRoot":"","sources":["../src/getUserConfig.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"getUserConfig.d.ts","sourceRoot":"","sources":["../src/getUserConfig.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAMxF,wBAAsB,aAAa,CAC/B,SAAS,GAAE,wBAAwB,GAAG,IAAW,EACjD,MAAM,GAAE,QAAQ,GAAG,OAAiB,GACrC,OAAO,CAAC,uBAAuB,CAAC,CAyBlC"}
|
package/dist/getUserConfig.js
CHANGED
|
@@ -5,7 +5,7 @@ import { frameworkConfigValidator } from "./frameworkConfigSchema.js";
|
|
|
5
5
|
import { makeFinalConfig } from "./makeFinalConfig.js";
|
|
6
6
|
import { throwError } from "./throwError.js";
|
|
7
7
|
import { cliOut } from "./cliOutput.js";
|
|
8
|
-
export async function getUserConfig(volume = 'noisy') {
|
|
8
|
+
export async function getUserConfig(overrides = null, volume = 'noisy') {
|
|
9
9
|
const userConfigOrNull = await findUserConfig(process.cwd(), volume);
|
|
10
10
|
//frameworkCon
|
|
11
11
|
if (userConfigOrNull !== null) {
|
|
@@ -15,11 +15,11 @@ export async function getUserConfig(volume = 'noisy') {
|
|
|
15
15
|
cliOut('Config', userConfig);
|
|
16
16
|
throwError('Your tungsten config did not match the required format', JSON.stringify(result.flatProblemsByPath));
|
|
17
17
|
}
|
|
18
|
-
const finalConfig = makeFinalConfig(result);
|
|
18
|
+
const finalConfig = makeFinalConfig(result, overrides);
|
|
19
19
|
//console.log('finalConfig', finalConfig)
|
|
20
20
|
return finalConfig;
|
|
21
21
|
//return makeFinalConfig(userConfig.data)
|
|
22
22
|
} else {
|
|
23
|
-
return defaultConfig;
|
|
23
|
+
return makeFinalConfig(defaultConfig, overrides);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { FrameworkConfig, FrameworkConfigComplete } from './FrameworkConfig.js';
|
|
2
|
-
export declare function makeFinalConfig(userConfig: FrameworkConfig): FrameworkConfigComplete;
|
|
1
|
+
import type { FrameworkConfig, FrameworkConfigComplete, FrameworkConfigOverrides } from './FrameworkConfig.js';
|
|
2
|
+
export declare function makeFinalConfig(userConfig: FrameworkConfig, overrides?: FrameworkConfigOverrides | null): FrameworkConfigComplete;
|
|
3
3
|
//# sourceMappingURL=makeFinalConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeFinalConfig.d.ts","sourceRoot":"","sources":["../src/makeFinalConfig.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"makeFinalConfig.d.ts","sourceRoot":"","sources":["../src/makeFinalConfig.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACR,eAAe,EAAE,uBAAuB,EAAE,wBAAwB,EACrE,MAAM,sBAAsB,CAAA;AAG7B,wBAAgB,eAAe,CAC3B,UAAU,EAAE,eAAe,EAC3B,SAAS,GAAE,wBAAwB,GAAG,IAAW,GAClD,uBAAuB,CAiBzB"}
|
package/dist/makeFinalConfig.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { defaultConfig } from "./defaultConfig.js";
|
|
2
|
-
export function makeFinalConfig(userConfig) {
|
|
2
|
+
export function makeFinalConfig(userConfig, overrides = null) {
|
|
3
3
|
const finalConfig = structuredClone(defaultConfig);
|
|
4
4
|
for (const key in userConfig) {
|
|
5
5
|
//if (Object.prototype.hasOwnProperty.call(userConfig, key)) { // github co-pilot suggestion, unsure if needed
|
|
6
6
|
finalConfig[key] = userConfig[key]; // eslint-disable-line no-type-assertion/no-type-assertion
|
|
7
7
|
//}
|
|
8
8
|
}
|
|
9
|
+
// an override left undefined keeps the user config / default value
|
|
10
|
+
for (const key in overrides) {
|
|
11
|
+
const value = overrides[key];
|
|
12
|
+
if (value === undefined) continue;
|
|
13
|
+
finalConfig[key] = value; // eslint-disable-line no-type-assertion/no-type-assertion
|
|
14
|
+
}
|
|
9
15
|
return finalConfig;
|
|
10
16
|
}
|
|
@@ -21,7 +21,7 @@ export function ensureTestEnvLoaded() {
|
|
|
21
21
|
if (loadPromise === undefined) {
|
|
22
22
|
loadPromise = (async () => {
|
|
23
23
|
if (!testEnvIsRequested(process.env[testEnvVariableName])) return;
|
|
24
|
-
const config = await getUserConfig('silent');
|
|
24
|
+
const config = await getUserConfig({}, 'silent');
|
|
25
25
|
// iteration 0: schemas are stable within a test run.
|
|
26
26
|
// _firstLoad = false: suppress the CLI boot output.
|
|
27
27
|
// useTestEnvFiles = true: prefer .env.test* files.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tungsten",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": "./dist/index.js",
|
|
12
|
+
"./compat": "./dist/compat/index.js",
|
|
12
13
|
"./react-zone": "./dist/zones/react.js",
|
|
13
14
|
"./testing": "./dist/testing/index.js",
|
|
14
15
|
"./*": "./dist/*",
|