@_linked/cli 1.14.0 → 1.16.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/CHANGELOG.md +123 -0
- package/README.md +19 -22
- package/defaults/app-react-native/README.md +4 -4
- package/defaults/app-react-native/apps/mobile/__tests__/composePort.test.ts +33 -0
- package/defaults/app-react-native/apps/mobile/__tests__/integration/apiEnv.ts +27 -1
- package/defaults/app-react-native/apps/mobile/__tests__/integration/globalSetup.ts +11 -7
- package/defaults/app-react-native/apps/mobile/jest.integration.config.js +1 -1
- package/defaults/app-react-native/apps/mobile/src/components/PersonOverview.tsx +1 -1
- package/defaults/app-react-native/apps/mobile/src/components/PersonPreview.tsx +1 -1
- package/defaults/app-react-native/packages/app-shapes/package.json +0 -3
- package/lib/esm/cli-methods.d.ts +29 -1
- package/lib/esm/cli-methods.d.ts.map +1 -1
- package/lib/esm/cli-methods.js +151 -169
- package/lib/esm/cli-methods.js.map +1 -1
- package/lib/esm/cli.js +18 -8
- package/lib/esm/cli.js.map +1 -1
- package/lib/esm/commands/start.d.ts +12 -0
- package/lib/esm/commands/start.d.ts.map +1 -1
- package/lib/esm/commands/start.js +63 -9
- package/lib/esm/commands/start.js.map +1 -1
- package/lib/esm/utils/esmSpecifiers.d.ts +5 -1
- package/lib/esm/utils/esmSpecifiers.d.ts.map +1 -1
- package/lib/esm/utils/esmSpecifiers.js +44 -10
- package/lib/esm/utils/esmSpecifiers.js.map +1 -1
- package/lib/esm/utils.d.ts +16 -7
- package/lib/esm/utils.d.ts.map +1 -1
- package/lib/esm/utils.js +92 -40
- package/lib/esm/utils.js.map +1 -1
- package/lib/esm/vite-config.d.ts +17 -0
- package/lib/esm/vite-config.d.ts.map +1 -1
- package/lib/esm/vite-config.js +42 -8
- package/lib/esm/vite-config.js.map +1 -1
- package/package.json +2 -2
package/lib/esm/cli-methods.js
CHANGED
|
@@ -14,7 +14,7 @@ import { getEnvFile } from 'env-cmd/dist/get-env-vars.js';
|
|
|
14
14
|
import fs from 'fs-extra';
|
|
15
15
|
import path, { dirname } from 'path';
|
|
16
16
|
import { createInterface } from 'readline';
|
|
17
|
-
import { debugInfo, execp, execPromise, getFileImports, getFiles, getLastCommitTime, getPackageJSON, isImportOutsideOfPackage,
|
|
17
|
+
import { debugInfo, execp, execPromise, getFileImports, getFiles, getLastCommitTime, getPackageJSON, isImportOutsideOfPackage, isInternalLinkedImport, needsRebuilding, } from './utils.js';
|
|
18
18
|
import { renameShippedDotfiles } from './utils/shippedDotfiles.js';
|
|
19
19
|
import { planPackageSetup } from './utils/packageSetup.js';
|
|
20
20
|
import { rewriteExtensionlessImports } from './utils/esmSpecifiers.js';
|
|
@@ -124,7 +124,7 @@ export const createApp = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...ar
|
|
|
124
124
|
// Scaffold from the canonical template repo (single source of truth; CN's
|
|
125
125
|
// server-side createProject clones the same repo). Shallow clone, then drop
|
|
126
126
|
// .git so the new app starts with clean history.
|
|
127
|
-
yield execPromise(`git clone --depth 1 https://github.com/linked-
|
|
127
|
+
yield execPromise(`git clone --depth 1 https://github.com/linked-fw/app-template.git "${targetFolder}"`, false, false);
|
|
128
128
|
fs.removeSync(path.join(targetFolder, '.git'));
|
|
129
129
|
//make sure the data folder exists (even though its empty).. copying empty folders does not work with fs.copySync
|
|
130
130
|
fs.mkdirSync(path.join(targetFolder, 'data'), { recursive: true });
|
|
@@ -137,19 +137,7 @@ export const createApp = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...ar
|
|
|
137
137
|
if (fs.existsSync(gitignoreTemplate)) {
|
|
138
138
|
fs.renameSync(gitignoreTemplate, path.join(targetFolder, '.gitignore'));
|
|
139
139
|
}
|
|
140
|
-
|
|
141
|
-
if (fs.existsSync(yarnrcTemplate)) {
|
|
142
|
-
fs.renameSync(yarnrcTemplate, path.join(targetFolder, '.yarnrc.yml'));
|
|
143
|
-
}
|
|
144
|
-
// Mark the new app as a self-contained Yarn project root. Without this,
|
|
145
|
-
// Yarn climbs ancestor dirs looking for the project root and may decide
|
|
146
|
-
// a stray yarn.lock further up the tree is "the project" — aborting
|
|
147
|
-
// install with "the nearest package directory doesn't seem to be part
|
|
148
|
-
// of the project declared in <ancestor>".
|
|
149
|
-
const yarnLockPath = path.join(targetFolder, 'yarn.lock');
|
|
150
|
-
if (!fs.existsSync(yarnLockPath)) {
|
|
151
|
-
fs.writeFileSync(yarnLockPath, '');
|
|
152
|
-
}
|
|
140
|
+
stripYarnProjectFiles(targetFolder);
|
|
153
141
|
// Seed the real (gitignored) Layer 2 config from the committed example so
|
|
154
142
|
// the scaffolded app boots first try. Users can edit either file later.
|
|
155
143
|
const datasetsExample = path.join(targetFolder, 'linked.backend.datasets.example.json');
|
|
@@ -165,17 +153,13 @@ export const createApp = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...ar
|
|
|
165
153
|
// create-app stamps this app's identity into the clone directly rather than
|
|
166
154
|
// relying on ${var} substitution.
|
|
167
155
|
applyAppIdentity(targetFolder, { appName, appPrefix, hyphenName });
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
options.appDomain);
|
|
174
|
-
const pm = yield choosePackageManager(interactive);
|
|
156
|
+
// New apps are npm apps: npm is the package manager the templates, the CI
|
|
157
|
+
// workflows and the published @_linked/* packages are all tested against, and
|
|
158
|
+
// the react-native template already installs with npm. Keeping a single
|
|
159
|
+
// package manager also keeps the scaffolded app to a single lockfile.
|
|
160
|
+
const pm = CREATE_APP_PACKAGE_MANAGER;
|
|
175
161
|
if (!options.skipInstall) {
|
|
176
|
-
const installCommand = pm
|
|
177
|
-
? 'export NODE_OPTIONS="--no-network-family-autoselection" && yarn install'
|
|
178
|
-
: 'npm install';
|
|
162
|
+
const installCommand = installCommandFor(pm);
|
|
179
163
|
const spinner = ora({
|
|
180
164
|
text: `Installing dependencies (${pm})...`,
|
|
181
165
|
spinner: 'dots',
|
|
@@ -207,7 +191,7 @@ export const createApp = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...ar
|
|
|
207
191
|
}
|
|
208
192
|
}
|
|
209
193
|
}
|
|
210
|
-
const startCommand = pm
|
|
194
|
+
const startCommand = startCommandFor(pm);
|
|
211
195
|
log(`Your Linked app is ready at ${chalk.blueBright(targetFolder)}`, `\nStorage: linked.backend.storage.ts wires aliases to stores; linked.backend.datasets.json holds endpoints.`, `Defaults to Fuseki at ${chalk.cyan('http://localhost:3030')} (auto-creates the dataset on first boot).`, `Make sure Fuseki is running, e.g.:`, ` ${chalk.blueBright('docker run -d --rm -p 3030:3030 --name fuseki stain/jena-fuseki')}`, `Edit ${chalk.cyan('linked.backend.datasets.json')} to change endpoints or credentials.`, `Mirror file for the frontend: ${chalk.cyan('src/linked.frontend.storage.ts')} + ${chalk.cyan('src/linked.frontend.datasets.json')}.`, `\nTo start:`, ` ${chalk.blueBright(`cd ${hyphenName} && ${startCommand}`)}`);
|
|
212
196
|
});
|
|
213
197
|
/**
|
|
@@ -391,9 +375,26 @@ function setEnvVar(envText, key, value) {
|
|
|
391
375
|
* - `src/package.ts`: the runtime `linkedPackage` id — shape URIs derive from it.
|
|
392
376
|
* - pm2 process names + the VS Code launch name (cosmetic, but should match).
|
|
393
377
|
*/
|
|
378
|
+
/**
|
|
379
|
+
* Scaffolded apps are npm apps, so the new app must not also look like a yarn
|
|
380
|
+
* project. Removes every yarn project file a template clone may still carry —
|
|
381
|
+
* including the legacy `yarnrc.yml.template` that create-app used to rename
|
|
382
|
+
* into `.yarnrc.yml`. (No empty `yarn.lock` is written any more either; that
|
|
383
|
+
* file only existed to pin down Yarn's project-root search.)
|
|
384
|
+
*/
|
|
385
|
+
export function stripYarnProjectFiles(targetFolder) {
|
|
386
|
+
for (const yarnLeftover of [
|
|
387
|
+
'yarnrc.yml.template',
|
|
388
|
+
'.yarnrc.yml',
|
|
389
|
+
'.yarn',
|
|
390
|
+
'yarn.lock',
|
|
391
|
+
]) {
|
|
392
|
+
fs.removeSync(path.join(targetFolder, yarnLeftover));
|
|
393
|
+
}
|
|
394
|
+
}
|
|
394
395
|
function applyAppIdentity(targetFolder, ids) {
|
|
395
396
|
const { appName, appPrefix, hyphenName } = ids;
|
|
396
|
-
// 1. .env.example (+ seed .env from it so the first `
|
|
397
|
+
// 1. .env.example (+ seed .env from it so the first `npm start` is correct).
|
|
397
398
|
const envExample = path.join(targetFolder, '.env.example');
|
|
398
399
|
if (fs.existsSync(envExample)) {
|
|
399
400
|
let env = fs.readFileSync(envExample, 'utf8');
|
|
@@ -1240,48 +1241,20 @@ const replaceVariablesInFolder = function (folder) {
|
|
|
1240
1241
|
const replaceVariablesInFilesWithRoot = function (root, ...files) {
|
|
1241
1242
|
return replaceVariablesInFiles(...files.map((f) => path.join(root, f)));
|
|
1242
1243
|
};
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
}
|
|
1254
|
-
function detectPackageManagers() {
|
|
1255
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1256
|
-
const found = [];
|
|
1257
|
-
if (yield isAvailable('npm'))
|
|
1258
|
-
found.push('npm');
|
|
1259
|
-
if (yield isAvailable('yarn'))
|
|
1260
|
-
found.push('yarn');
|
|
1261
|
-
return found;
|
|
1262
|
-
});
|
|
1244
|
+
/**
|
|
1245
|
+
* The package manager `create-app` scaffolds with. Both templates (web and
|
|
1246
|
+
* react-native) install with npm, so a scaffolded app has exactly one lockfile.
|
|
1247
|
+
*/
|
|
1248
|
+
export const CREATE_APP_PACKAGE_MANAGER = 'npm';
|
|
1249
|
+
/** The shell command that installs a scaffolded app's dependencies. */
|
|
1250
|
+
export function installCommandFor(pm) {
|
|
1251
|
+
return pm === 'yarn'
|
|
1252
|
+
? 'export NODE_OPTIONS="--no-network-family-autoselection" && yarn install'
|
|
1253
|
+
: 'npm install';
|
|
1263
1254
|
}
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
if (available.length === 0) {
|
|
1268
|
-
throw new Error('Neither npm nor yarn is available on PATH. Install one and retry.');
|
|
1269
|
-
}
|
|
1270
|
-
if (available.length === 1)
|
|
1271
|
-
return available[0];
|
|
1272
|
-
if (!interactive) {
|
|
1273
|
-
// Match the historical default: prefer yarn when both are installed.
|
|
1274
|
-
return available.includes('yarn') ? 'yarn' : 'npm';
|
|
1275
|
-
}
|
|
1276
|
-
const fallback = available.includes('yarn') ? 'yarn' : 'npm';
|
|
1277
|
-
const answer = yield promptUser(`Package manager [${available.join('/')}] (default: ${chalk.gray(fallback)}): `);
|
|
1278
|
-
const choice = answer.trim().toLowerCase();
|
|
1279
|
-
if (choice === 'npm' || choice === 'yarn') {
|
|
1280
|
-
if (available.includes(choice))
|
|
1281
|
-
return choice;
|
|
1282
|
-
}
|
|
1283
|
-
return fallback;
|
|
1284
|
-
});
|
|
1255
|
+
/** The command printed to the user for starting their new app. */
|
|
1256
|
+
export function startCommandFor(pm) {
|
|
1257
|
+
return pm === 'yarn' ? 'yarn start' : 'npm start';
|
|
1285
1258
|
}
|
|
1286
1259
|
const ensureFolderExists = function (...folders) {
|
|
1287
1260
|
let target;
|
|
@@ -1400,9 +1373,10 @@ export const createComponent = (name_1, ...args_1) => __awaiter(void 0, [name_1,
|
|
|
1400
1373
|
log(`Added an import of this file from ${chalk.magenta(indexPath)}`);
|
|
1401
1374
|
}
|
|
1402
1375
|
});
|
|
1403
|
-
//
|
|
1404
|
-
//
|
|
1405
|
-
//
|
|
1376
|
+
// Reads the source of all ts/tsx files in the src folder and fails on imports
|
|
1377
|
+
// that reach outside the package source root ('outside_package'), or that point
|
|
1378
|
+
// into another Linked package's /src/ or /lib/ ('internal_linked'). Extensionless relative
|
|
1379
|
+
// imports are fine: `linked build` rewrites the emitted ESM specifiers.
|
|
1406
1380
|
export const checkImports = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (sourceFolder = getSourceFolder(), depth = 0, // Used to check if the import is outside the src folder
|
|
1407
1381
|
invalidImports = new Map()) {
|
|
1408
1382
|
if (!fs.existsSync(sourceFolder)) {
|
|
@@ -1413,12 +1387,8 @@ invalidImports = new Map()) {
|
|
|
1413
1387
|
// Start checking each file in the source folder
|
|
1414
1388
|
for (const file of dir) {
|
|
1415
1389
|
const filename = path.join(sourceFolder, file);
|
|
1416
|
-
// Skip test sources. Test files (and their helpers/probes)
|
|
1417
|
-
//
|
|
1418
|
-
// isn't load-bearing for them; enforcing it only blocks `linked build`
|
|
1419
|
-
// (the real ESM-output gate stays in force for shipped source). This is
|
|
1420
|
-
// what makes `linked build` green for packages whose tests use
|
|
1421
|
-
// extensionless imports (e.g. @_linked/core).
|
|
1390
|
+
// Skip test sources. Test files (and their helpers/probes) are not part
|
|
1391
|
+
// of the shipped package, so the import rules do not apply to them.
|
|
1422
1392
|
if (/(?:^|[\\/])(?:tests?|__tests__|test-helpers)(?:[\\/]|$)/.test(filename) ||
|
|
1423
1393
|
/\.(?:test|spec)\.tsx?$/.test(file) ||
|
|
1424
1394
|
/^type-probe.*\.tsx?$/.test(file)) {
|
|
@@ -1432,16 +1402,13 @@ invalidImports = new Map()) {
|
|
|
1432
1402
|
if (statSync(filename).isDirectory()) {
|
|
1433
1403
|
yield checkImports(filename, depth + 1, invalidImports);
|
|
1434
1404
|
}
|
|
1435
|
-
else {
|
|
1436
|
-
// Ignore all files that aren't one of the following:
|
|
1437
|
-
// - .ts
|
|
1438
|
-
// - .tsx
|
|
1439
|
-
continue;
|
|
1440
|
-
}
|
|
1441
1405
|
}
|
|
1442
1406
|
catch (e) {
|
|
1443
1407
|
console.log(e);
|
|
1444
1408
|
}
|
|
1409
|
+
// A directory has now been recursed into, and any other file is not a
|
|
1410
|
+
// source file: either way there is nothing here to read imports from.
|
|
1411
|
+
continue;
|
|
1445
1412
|
}
|
|
1446
1413
|
const allImports = yield getFileImports(filename);
|
|
1447
1414
|
if (!invalidImports.has(filename)) {
|
|
@@ -1454,15 +1421,9 @@ invalidImports = new Map()) {
|
|
|
1454
1421
|
importPath: i,
|
|
1455
1422
|
});
|
|
1456
1423
|
}
|
|
1457
|
-
if (
|
|
1424
|
+
if (isInternalLinkedImport(i)) {
|
|
1458
1425
|
invalidImports.get(filename).push({
|
|
1459
|
-
type: '
|
|
1460
|
-
importPath: i,
|
|
1461
|
-
});
|
|
1462
|
-
}
|
|
1463
|
-
if (isImportWithMissingExtension(i)) {
|
|
1464
|
-
invalidImports.get(filename).push({
|
|
1465
|
-
type: 'missing_extension',
|
|
1426
|
+
type: 'internal_linked',
|
|
1466
1427
|
importPath: i,
|
|
1467
1428
|
});
|
|
1468
1429
|
}
|
|
@@ -1481,26 +1442,22 @@ invalidImports = new Map()) {
|
|
|
1481
1442
|
if (type === 'outside_package') {
|
|
1482
1443
|
message += ' which is outside the package source root';
|
|
1483
1444
|
}
|
|
1484
|
-
if (type === '
|
|
1485
|
-
message +=
|
|
1486
|
-
' which should not contain /src/ or /lib/ in the import path';
|
|
1487
|
-
}
|
|
1488
|
-
if (type === 'missing_extension') {
|
|
1445
|
+
if (type === 'internal_linked') {
|
|
1489
1446
|
message +=
|
|
1490
|
-
|
|
1447
|
+
" which reaches into another Linked package's /src/ or /lib/." +
|
|
1448
|
+
' That breaks when its build layout changes and bypasses its' +
|
|
1449
|
+
' exports map. Import its public subpath instead.';
|
|
1491
1450
|
}
|
|
1492
1451
|
res += chalk.red(message + '\n');
|
|
1493
1452
|
});
|
|
1494
1453
|
});
|
|
1495
|
-
// Throw so buildStep aborts the compile pipeline
|
|
1496
|
-
//
|
|
1454
|
+
// Throw so buildStep aborts the compile pipeline: importing from outside
|
|
1455
|
+
// the package, or into another Linked package's /src/ or /lib/, breaks the
|
|
1456
|
+
// published package.
|
|
1497
1457
|
throw res;
|
|
1498
1458
|
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
// process.exit(0);
|
|
1502
|
-
return true;
|
|
1503
|
-
}
|
|
1459
|
+
// Nothing invalid: all imports OK.
|
|
1460
|
+
return true;
|
|
1504
1461
|
});
|
|
1505
1462
|
export const depCheckStaged = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1506
1463
|
console.log('Checking dependencies of staged files');
|
|
@@ -2202,7 +2159,6 @@ export const register = function (registryURL) {
|
|
|
2202
2159
|
}
|
|
2203
2160
|
};
|
|
2204
2161
|
export const buildPackage = (target_1, target2_1, ...args_1) => __awaiter(void 0, [target_1, target2_1, ...args_1], void 0, function* (target, target2, packagePath = process.cwd(), logResults = true) {
|
|
2205
|
-
var _a;
|
|
2206
2162
|
// Ensure packagePath is absolute and points to a directory containing package.json; if not, go up until we find one
|
|
2207
2163
|
// First, resolve to absolute path
|
|
2208
2164
|
let currentPath = path.isAbsolute(packagePath)
|
|
@@ -2276,7 +2232,20 @@ export const buildPackage = (target_1, target2_1, ...args_1) => __awaiter(void 0
|
|
|
2276
2232
|
}
|
|
2277
2233
|
return previousResult && true;
|
|
2278
2234
|
}
|
|
2279
|
-
else if (
|
|
2235
|
+
else if (
|
|
2236
|
+
//a step may report a detail alongside success, e.g. how many files
|
|
2237
|
+
//it changed. Not a warning: the build stays clean.
|
|
2238
|
+
stepResult &&
|
|
2239
|
+
typeof stepResult === 'object' &&
|
|
2240
|
+
stepResult.info) {
|
|
2241
|
+
if (logResults) {
|
|
2242
|
+
spinner.succeed(step.name + ' - ' + stepResult.info);
|
|
2243
|
+
}
|
|
2244
|
+
return previousResult && true;
|
|
2245
|
+
}
|
|
2246
|
+
else if (stepResult &&
|
|
2247
|
+
typeof stepResult === 'object' &&
|
|
2248
|
+
stepResult.error) {
|
|
2280
2249
|
if (logResults) {
|
|
2281
2250
|
spinner.fail(step.name + ' - ' + stepResult.error);
|
|
2282
2251
|
spinner.stop();
|
|
@@ -2287,13 +2256,21 @@ export const buildPackage = (target_1, target2_1, ...args_1) => __awaiter(void 0
|
|
|
2287
2256
|
//failed and should stop
|
|
2288
2257
|
return false;
|
|
2289
2258
|
}
|
|
2259
|
+
//anything else — notably a literal false, which several steps return
|
|
2260
|
+
//on failure — is a failure. Name the step, so the build does not end
|
|
2261
|
+
//on a bare 'Build failed'.
|
|
2262
|
+
const failure = step.name + ' failed';
|
|
2263
|
+
if (logResults) {
|
|
2264
|
+
spinner.fail(failure);
|
|
2265
|
+
spinner.stop();
|
|
2266
|
+
}
|
|
2267
|
+
else {
|
|
2268
|
+
console.error(chalk.red(failure));
|
|
2269
|
+
}
|
|
2270
|
+
return false;
|
|
2290
2271
|
});
|
|
2291
2272
|
});
|
|
2292
2273
|
};
|
|
2293
|
-
if (((_a = pkgJson.linked) === null || _a === void 0 ? void 0 : _a.extensionlessImports) === true) {
|
|
2294
|
-
const skipped = "Skipping the import check: package.json sets 'linked.extensionlessImports'";
|
|
2295
|
-
logResults ? spinner.info(skipped) : console.log(skipped);
|
|
2296
|
-
}
|
|
2297
2274
|
planBuildSteps(pkgJson, packagePath).forEach(buildStep);
|
|
2298
2275
|
let success = yield buildProcess.catch((err) => {
|
|
2299
2276
|
let msg = typeof err === 'string' || err instanceof Error
|
|
@@ -2306,22 +2283,21 @@ export const buildPackage = (target_1, target2_1, ...args_1) => __awaiter(void 0
|
|
|
2306
2283
|
symbol: chalk.red('✖'),
|
|
2307
2284
|
// text: 'Build failed',
|
|
2308
2285
|
});
|
|
2286
|
+
console.log(msg);
|
|
2309
2287
|
}
|
|
2310
2288
|
else {
|
|
2311
2289
|
console.error(chalk.red(packagePath.split('/').pop(), ' - Build failed:'));
|
|
2312
2290
|
console.error(err);
|
|
2313
|
-
return msg;
|
|
2314
2291
|
}
|
|
2315
|
-
|
|
2292
|
+
//a failed build always resolves to false, never to a truthy message:
|
|
2293
|
+
//callers decide success by the return value.
|
|
2294
|
+
return false;
|
|
2316
2295
|
});
|
|
2317
|
-
|
|
2318
|
-
if (typeof success !== 'undefined' && success !== false) {
|
|
2296
|
+
if (success === true) {
|
|
2319
2297
|
if (logResults) {
|
|
2320
2298
|
spinner.stopAndPersist({
|
|
2321
2299
|
symbol: chalk.greenBright('✔'),
|
|
2322
|
-
text:
|
|
2323
|
-
? 'Build successful'
|
|
2324
|
-
: 'Build successful with warnings',
|
|
2300
|
+
text: warned ? 'Build successful with warnings' : 'Build successful',
|
|
2325
2301
|
});
|
|
2326
2302
|
}
|
|
2327
2303
|
}
|
|
@@ -2333,52 +2309,31 @@ export const buildPackage = (target_1, target2_1, ...args_1) => __awaiter(void 0
|
|
|
2333
2309
|
});
|
|
2334
2310
|
}
|
|
2335
2311
|
}
|
|
2336
|
-
|
|
2312
|
+
//true only when every step succeeded (warnings included); false otherwise.
|
|
2313
|
+
return success === true;
|
|
2337
2314
|
});
|
|
2338
|
-
// The ordered `linked build` steps for a linkedPackage.
|
|
2339
|
-
//
|
|
2340
|
-
//
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
apply: () => checkImports(packagePath + '/src'),
|
|
2349
|
-
});
|
|
2350
|
-
}
|
|
2351
|
-
steps.push({
|
|
2315
|
+
// The ordered `linked build` steps for a linkedPackage. Source may use
|
|
2316
|
+
// extensionless relative imports: once `lib/esm` holds everything it will ship,
|
|
2317
|
+
// every package gets `.js` added to the relative specifiers in it (JS and
|
|
2318
|
+
// declarations). For a package that already writes `.js` this is a no-op.
|
|
2319
|
+
export const planBuildSteps = (pkgJson, packagePath) => [
|
|
2320
|
+
{
|
|
2321
|
+
name: 'Checking imports',
|
|
2322
|
+
apply: () => checkImports(packagePath + '/src'),
|
|
2323
|
+
},
|
|
2324
|
+
{
|
|
2352
2325
|
name: 'Compiling ESM',
|
|
2353
2326
|
apply: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2354
2327
|
return compilePackageESM(packagePath);
|
|
2355
2328
|
}),
|
|
2356
|
-
}
|
|
2357
|
-
|
|
2358
|
-
steps.push({
|
|
2359
|
-
name: 'Rewriting ESM import specifiers',
|
|
2360
|
-
apply: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2361
|
-
const libEsm = path.join(packagePath, 'lib', 'esm');
|
|
2362
|
-
if (!fs.existsSync(libEsm)) {
|
|
2363
|
-
return {
|
|
2364
|
-
error: "lib/esm was not emitted. 'linked.extensionlessImports' needs an ESM build: add tsconfig-esm.json to the package.",
|
|
2365
|
-
};
|
|
2366
|
-
}
|
|
2367
|
-
const { unresolved } = yield rewriteExtensionlessImports(libEsm);
|
|
2368
|
-
if (unresolved.length > 0) {
|
|
2369
|
-
return `could not resolve ${unresolved.length} import(s), left unchanged: ${unresolved.join(', ')}`;
|
|
2370
|
-
}
|
|
2371
|
-
return true;
|
|
2372
|
-
}),
|
|
2373
|
-
});
|
|
2374
|
-
}
|
|
2375
|
-
steps.push({
|
|
2329
|
+
},
|
|
2330
|
+
{
|
|
2376
2331
|
name: 'Compiling CJS',
|
|
2377
2332
|
apply: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2378
2333
|
return compilePackageCJS(packagePath);
|
|
2379
2334
|
}),
|
|
2380
|
-
}
|
|
2381
|
-
|
|
2335
|
+
},
|
|
2336
|
+
{
|
|
2382
2337
|
name: 'Copying files to lib folder',
|
|
2383
2338
|
apply: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2384
2339
|
const files = yield glob(packagePath + '/src/**/*.{json,d.ts,css,scss}');
|
|
@@ -2400,8 +2355,8 @@ export const planBuildSteps = (pkgJson, packagePath) => {
|
|
|
2400
2355
|
return allResults.every((r) => r === true);
|
|
2401
2356
|
});
|
|
2402
2357
|
}),
|
|
2403
|
-
}
|
|
2404
|
-
|
|
2358
|
+
},
|
|
2359
|
+
{
|
|
2405
2360
|
name: 'Dual package support',
|
|
2406
2361
|
apply: () => {
|
|
2407
2362
|
// Skip if no tsconfig files (e.g. pure-CSS packages).
|
|
@@ -2415,19 +2370,48 @@ export const planBuildSteps = (pkgJson, packagePath) => {
|
|
|
2415
2370
|
return res === '';
|
|
2416
2371
|
});
|
|
2417
2372
|
},
|
|
2418
|
-
}
|
|
2419
|
-
|
|
2373
|
+
},
|
|
2374
|
+
{
|
|
2420
2375
|
name: 'Removing old files from lib folder',
|
|
2421
2376
|
apply: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2422
2377
|
return removeOldFiles(packagePath);
|
|
2423
2378
|
}),
|
|
2424
|
-
}
|
|
2425
|
-
|
|
2379
|
+
},
|
|
2380
|
+
{
|
|
2381
|
+
// MUST run after 'Copying files to lib folder' and after 'Removing old
|
|
2382
|
+
// files from lib folder', because the rewrite resolves each specifier
|
|
2383
|
+
// against the files actually present in lib/esm:
|
|
2384
|
+
// - the copy step brings in the assets (`./x.scss`) and hand-written
|
|
2385
|
+
// `.d.ts` from src; before it, an asset import looks unresolvable (a
|
|
2386
|
+
// spurious "build with warnings") and a copied `.d.ts` is never rewritten;
|
|
2387
|
+
// - the cleanup step deletes stale output; before it, a leftover `x.js`
|
|
2388
|
+
// makes './x' resolve to './x.js' and the cleanup then removes the file
|
|
2389
|
+
// the specifier now points at.
|
|
2390
|
+
name: 'Rewriting ESM import specifiers',
|
|
2391
|
+
apply: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2392
|
+
// No tsconfig-esm.json means the ESM compile was skipped (e.g. pure-CSS
|
|
2393
|
+
// packages), so there is nothing to rewrite and nothing to fail over.
|
|
2394
|
+
if (!fs.existsSync(path.join(packagePath, 'tsconfig-esm.json'))) {
|
|
2395
|
+
return true;
|
|
2396
|
+
}
|
|
2397
|
+
const libEsm = path.join(packagePath, 'lib', 'esm');
|
|
2398
|
+
if (!fs.existsSync(libEsm)) {
|
|
2399
|
+
return {
|
|
2400
|
+
error: 'lib/esm was not emitted while tsconfig-esm.json is present. Check the ESM compile.',
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
const { changed, unresolved } = yield rewriteExtensionlessImports(libEsm);
|
|
2404
|
+
if (unresolved.length > 0) {
|
|
2405
|
+
return `could not resolve ${unresolved.length} import(s), left unchanged: ${unresolved.join(', ')}`;
|
|
2406
|
+
}
|
|
2407
|
+
return changed > 0 ? { info: `rewrote ${changed} file(s)` } : true;
|
|
2408
|
+
}),
|
|
2409
|
+
},
|
|
2410
|
+
{
|
|
2426
2411
|
name: 'Checking dependencies',
|
|
2427
2412
|
apply: () => depCheck(packagePath),
|
|
2428
|
-
}
|
|
2429
|
-
|
|
2430
|
-
};
|
|
2413
|
+
},
|
|
2414
|
+
];
|
|
2431
2415
|
export const compilePackage = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (packagePath = process.cwd()) {
|
|
2432
2416
|
//echo 'compiling CJS' && tsc -p tsconfig-cjs.json && echo 'compiling ESM' && tsc -p tsconfig-esm.json
|
|
2433
2417
|
// let cjsConfig = fs.existsSync(path.join(packagePath,'tsconfig-cjs.json'));
|
|
@@ -2751,12 +2735,10 @@ export var buildUpdated = function (back_1, target_1, target2_1) {
|
|
|
2751
2735
|
// log('path: ' + pathToBuild);
|
|
2752
2736
|
return buildPackage(null, null, pathToBuild, false)
|
|
2753
2737
|
.then((res) => {
|
|
2754
|
-
//
|
|
2755
|
-
//
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
if (typeof res === 'undefined' || typeof res === 'string') {
|
|
2759
|
-
logError('Failed to build ' + pkg.packageName + '. ' + res ? res : '');
|
|
2738
|
+
//buildPackage returns true only when the build succeeded
|
|
2739
|
+
//(warnings included); anything else is a failure.
|
|
2740
|
+
if (res !== true) {
|
|
2741
|
+
logError('Failed to build ' + pkg.packageName);
|
|
2760
2742
|
process.exit(1);
|
|
2761
2743
|
}
|
|
2762
2744
|
else {
|