@_linked/cli 1.44.0 → 1.45.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 +28 -0
- package/README.md +36 -2
- package/defaults/package/src/index.ts +0 -5
- package/defaults/package-ontology/src/index.ts +8 -0
- package/defaults/shape.ts +13 -10
- package/lib/esm/cli-methods.d.ts +10 -1
- package/lib/esm/cli-methods.d.ts.map +1 -1
- package/lib/esm/cli-methods.js +252 -97
- package/lib/esm/cli-methods.js.map +1 -1
- package/lib/esm/cli.js +60 -17
- package/lib/esm/cli.js.map +1 -1
- package/lib/esm/commands/localize.d.ts.map +1 -1
- package/lib/esm/commands/localize.js +2 -1
- package/lib/esm/commands/localize.js.map +1 -1
- package/lib/esm/localize/localize.d.ts.map +1 -1
- package/lib/esm/localize/localize.js +25 -3
- package/lib/esm/localize/localize.js.map +1 -1
- package/lib/esm/utils/createPackageLocation.d.ts +20 -5
- package/lib/esm/utils/createPackageLocation.d.ts.map +1 -1
- package/lib/esm/utils/createPackageLocation.js +9 -14
- package/lib/esm/utils/createPackageLocation.js.map +1 -1
- package/lib/esm/utils/packageBaseUri.d.ts +27 -0
- package/lib/esm/utils/packageBaseUri.d.ts.map +1 -0
- package/lib/esm/utils/packageBaseUri.js +91 -0
- package/lib/esm/utils/packageBaseUri.js.map +1 -0
- package/lib/esm/utils/packageKind.d.ts +49 -0
- package/lib/esm/utils/packageKind.d.ts.map +1 -0
- package/lib/esm/utils/packageKind.js +94 -0
- package/lib/esm/utils/packageKind.js.map +1 -0
- package/lib/esm/utils/relinkHooks.d.ts +19 -0
- package/lib/esm/utils/relinkHooks.d.ts.map +1 -0
- package/lib/esm/utils/relinkHooks.js +74 -0
- package/lib/esm/utils/relinkHooks.js.map +1 -0
- package/package.json +2 -2
- /package/defaults/{package → package-ontology}/src/data/example-ontology.json +0 -0
- /package/defaults/{package → package-ontology}/src/data/example-ontology.json.d.ts +0 -0
- /package/defaults/{package → package-ontology}/src/ontologies/example-ontology.register.ts +0 -0
- /package/defaults/{package → package-ontology}/src/ontologies/example-ontology.ts +0 -0
package/lib/esm/cli-methods.js
CHANGED
|
@@ -33,10 +33,38 @@ import ora from 'ora';
|
|
|
33
33
|
import stagedGitFiles from 'staged-git-files';
|
|
34
34
|
import { packagePublishesCjs } from './package-manifest.js';
|
|
35
35
|
import { asNamespace, defaultOntologyNamespace } from './utils/ontologyNamespace.js';
|
|
36
|
+
import { decidePackageKind, ontologySlugFor, packageNameFor, scaffoldKinds, PACKAGE_TEMPLATE_DIRS, SHARED_TEMPLATE_FILES, } from './utils/packageKind.js';
|
|
37
|
+
import { resolvePackageBaseUri, withBaseUri } from './utils/packageBaseUri.js';
|
|
36
38
|
let dirname__ = typeof __dirname !== 'undefined'
|
|
37
39
|
? __dirname
|
|
38
40
|
: //@ts-ignore
|
|
39
41
|
dirname(import.meta.url).replace('file:/', '');
|
|
42
|
+
/**
|
|
43
|
+
* A folder under this package's `defaults/`. The built module sits in `lib/esm/`
|
|
44
|
+
* and the source in `src/`, so the templates are two or one level up.
|
|
45
|
+
*/
|
|
46
|
+
function defaultsDir(...parts) {
|
|
47
|
+
var _a;
|
|
48
|
+
const candidates = [
|
|
49
|
+
path.join(dirname__, '..', '..', 'defaults'),
|
|
50
|
+
path.join(dirname__, '..', 'defaults'),
|
|
51
|
+
];
|
|
52
|
+
const root = (_a = candidates.find((dir) => fs.existsSync(dir))) !== null && _a !== void 0 ? _a : candidates[0];
|
|
53
|
+
return path.join(root, ...parts);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The commands that write a file importing `../package.js` need a `src/package.ts`
|
|
57
|
+
* to import. A new app root has none (it is a linkedApp, not a linkedPackage), so
|
|
58
|
+
* there the import would be broken: refuse instead. Only the file decides: a
|
|
59
|
+
* linkedApp that keeps its shapes at its root with its own `src/package.ts`, as
|
|
60
|
+
* create-now does, is served as before.
|
|
61
|
+
*/
|
|
62
|
+
function assertInsidePackage(sourceFolder, command) {
|
|
63
|
+
if (fs.existsSync(path.join(sourceFolder, 'package.ts')))
|
|
64
|
+
return;
|
|
65
|
+
throw new CreatePackageError(`${command}: no src/package.ts here, so there is no package to add to. An app root is ` +
|
|
66
|
+
`not a package; run this inside a package (packages/<name>).`);
|
|
67
|
+
}
|
|
40
68
|
/**
|
|
41
69
|
* Dynamically import the app's backend storage configuration. Tries the
|
|
42
70
|
* canonical `linked.backend.storage.{ts,js}` at app root first, then the
|
|
@@ -376,8 +404,12 @@ function setEnvVar(envText, key, value) {
|
|
|
376
404
|
* - `.env.example` (committed defaults for this app) + `.env` (local): APP_NAME
|
|
377
405
|
* drives the display name; APP_PREFIX names data files.
|
|
378
406
|
* - `package.json`: `name` (hyphenated id) + `displayName` (human name).
|
|
379
|
-
* - `src/package.ts`: the runtime `linkedPackage` id — shape URIs derive from it.
|
|
380
407
|
* - pm2 process names + the VS Code launch name (cosmetic, but should match).
|
|
408
|
+
*
|
|
409
|
+
* Nothing under `src/` is touched: the app is a linkedApp, not a linked package,
|
|
410
|
+
* so its root registers no package and has no package id to stamp. Its shapes
|
|
411
|
+
* live in its packages (`packages/<name>-assets`), each with its own
|
|
412
|
+
* `src/package.ts`.
|
|
381
413
|
*/
|
|
382
414
|
/**
|
|
383
415
|
* Scaffolded apps are npm apps, so the new app must not also look like a yarn
|
|
@@ -396,7 +428,7 @@ export function stripYarnProjectFiles(targetFolder) {
|
|
|
396
428
|
fs.removeSync(path.join(targetFolder, yarnLeftover));
|
|
397
429
|
}
|
|
398
430
|
}
|
|
399
|
-
function applyAppIdentity(targetFolder, ids) {
|
|
431
|
+
export function applyAppIdentity(targetFolder, ids) {
|
|
400
432
|
const { appName, appPrefix, hyphenName } = ids;
|
|
401
433
|
// 1. .env.example (+ seed .env from it so the first `npm start` is correct).
|
|
402
434
|
const envExample = path.join(targetFolder, '.env.example');
|
|
@@ -417,13 +449,7 @@ function applyAppIdentity(targetFolder, ids) {
|
|
|
417
449
|
pkg.displayName = appName;
|
|
418
450
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
419
451
|
}
|
|
420
|
-
// 3.
|
|
421
|
-
const packageTs = path.join(targetFolder, 'src', 'package.ts');
|
|
422
|
-
if (fs.existsSync(packageTs)) {
|
|
423
|
-
const src = fs.readFileSync(packageTs, 'utf8');
|
|
424
|
-
fs.writeFileSync(packageTs, src.replace(/linkedPackage\(\s*['"][^'"]*['"]\s*\)/, `linkedPackage('${hyphenName}')`));
|
|
425
|
-
}
|
|
426
|
-
// 4. pm2 process names + VS Code launch name (template hardcodes 'app').
|
|
452
|
+
// 3. pm2 process names + VS Code launch name (template hardcodes 'app').
|
|
427
453
|
const renames = [
|
|
428
454
|
['pm2.config.js', /name:\s*'app'/, `name: '${hyphenName}'`],
|
|
429
455
|
['pm2-staging.config.js', /name:\s*'app-staging'/, `name: '${hyphenName}-staging'`],
|
|
@@ -1043,6 +1069,7 @@ export const createOntology = (prefix_1, uriBase_1, ...args_1) => __awaiter(void
|
|
|
1043
1069
|
return;
|
|
1044
1070
|
}
|
|
1045
1071
|
let sourceFolder = getSourceFolder(basePath);
|
|
1072
|
+
assertInsidePackage(sourceFolder, 'create-ontology');
|
|
1046
1073
|
let targetFolder = ensureFolderExists(sourceFolder, 'ontologies');
|
|
1047
1074
|
if (!uriBase) {
|
|
1048
1075
|
uriBase = defaultOntologyNamespace(prefix);
|
|
@@ -1053,16 +1080,16 @@ export const createOntology = (prefix_1, uriBase_1, ...args_1) => __awaiter(void
|
|
|
1053
1080
|
log("Creating files for ontology '" + prefix + "'");
|
|
1054
1081
|
let targetFile = path.join(targetFolder, hyphenName + '.ts');
|
|
1055
1082
|
let targetRegisterFile = path.join(targetFolder, hyphenName + '.register.ts');
|
|
1056
|
-
fs.copySync(
|
|
1083
|
+
fs.copySync(defaultsDir('package-ontology', 'src', 'ontologies', 'example-ontology.ts'), targetFile);
|
|
1057
1084
|
// The registration sibling. It has to be a separate module: registration needs the
|
|
1058
1085
|
// ontology module's whole export namespace, and a module cannot import itself once a
|
|
1059
1086
|
// bundler is involved -- Rollup elides the self-reference and the app dies at boot.
|
|
1060
|
-
fs.copySync(
|
|
1087
|
+
fs.copySync(defaultsDir('package-ontology', 'src', 'ontologies', 'example-ontology.register.ts'), targetRegisterFile);
|
|
1061
1088
|
//copy data files
|
|
1062
1089
|
let targetDataFile = path.join(targetFolder, '..', 'data', hyphenName + '.json');
|
|
1063
1090
|
let targetDataFile2 = path.join(targetFolder, '..', 'data', hyphenName + '.json.d.ts');
|
|
1064
|
-
fs.copySync(
|
|
1065
|
-
fs.copySync(
|
|
1091
|
+
fs.copySync(defaultsDir('package-ontology', 'src', 'data', 'example-ontology.json'), targetDataFile);
|
|
1092
|
+
fs.copySync(defaultsDir('package-ontology', 'src', 'data', 'example-ontology.json.d.ts'), targetDataFile2);
|
|
1066
1093
|
yield replaceVariablesInFiles(targetFile, targetRegisterFile, targetDataFile, targetDataFile2);
|
|
1067
1094
|
log(`Prepared a new ontology data files in ${chalk.magenta(targetDataFile.replace(basePath, ''))}`, `And an ontology accessor file in ${chalk.magenta(targetFile.replace(basePath, ''))}`);
|
|
1068
1095
|
//if this is not a lincd app (but a lincd package instead)
|
|
@@ -1261,12 +1288,13 @@ export const getScriptDir = () => {
|
|
|
1261
1288
|
};
|
|
1262
1289
|
export const createShape = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...args_1], void 0, function* (name, basePath = process.cwd()) {
|
|
1263
1290
|
let sourceFolder = getSourceFolder(basePath);
|
|
1291
|
+
assertInsidePackage(sourceFolder, 'create-shape');
|
|
1264
1292
|
let targetFolder = ensureFolderExists(sourceFolder, 'shapes');
|
|
1265
1293
|
let { hyphenName, camelCaseName, underscoreName } = setNameVariables(name);
|
|
1266
1294
|
//copy default shape file
|
|
1267
1295
|
// log("Creating files for shape '" + name + "'");
|
|
1268
1296
|
let targetFile = path.join(targetFolder, hyphenName + '.ts');
|
|
1269
|
-
fs.copySync(
|
|
1297
|
+
fs.copySync(defaultsDir('shape.ts'), targetFile);
|
|
1270
1298
|
//replace variables in some of the copied files
|
|
1271
1299
|
yield replaceVariablesInFiles(targetFile);
|
|
1272
1300
|
log(`Created a new shape class template in ${chalk.magenta(targetFile.replace(basePath, ''))}`);
|
|
@@ -1279,14 +1307,15 @@ export const createShape = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...
|
|
|
1279
1307
|
log(`Registered the shape in ${chalk.magenta(barrelPath.replace(basePath, ''))}`);
|
|
1280
1308
|
});
|
|
1281
1309
|
export const createSetComponent = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...args_1], void 0, function* (name, basePath = process.cwd()) {
|
|
1310
|
+
assertInsidePackage(path.join(basePath, 'src'), 'create-set-component');
|
|
1282
1311
|
let targetFolder = ensureFolderExists(basePath, 'src', 'components');
|
|
1283
1312
|
let { hyphenName, camelCaseName, underscoreName } = setNameVariables(name);
|
|
1284
1313
|
//copy default shape file
|
|
1285
1314
|
log("Creating files for set component '" + name + "'");
|
|
1286
1315
|
let targetFile = path.join(targetFolder, hyphenName + '.tsx');
|
|
1287
|
-
fs.copySync(
|
|
1316
|
+
fs.copySync(defaultsDir('set-component.tsx'), targetFile);
|
|
1288
1317
|
let targetFile2 = path.join(targetFolder, hyphenName + '.scss');
|
|
1289
|
-
fs.copySync(
|
|
1318
|
+
fs.copySync(defaultsDir('component.scss'), targetFile2);
|
|
1290
1319
|
//replace variables in some of the copied files
|
|
1291
1320
|
yield replaceVariablesInFiles(targetFile, targetFile2);
|
|
1292
1321
|
let indexPath = addLineToIndex(`import './components/${hyphenName}.js';`, 'components');
|
|
@@ -1294,14 +1323,15 @@ export const createSetComponent = (name_1, ...args_1) => __awaiter(void 0, [name
|
|
|
1294
1323
|
});
|
|
1295
1324
|
export const createComponent = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...args_1], void 0, function* (name, basePath = process.cwd()) {
|
|
1296
1325
|
let sourceFolder = getSourceFolder(basePath);
|
|
1326
|
+
assertInsidePackage(sourceFolder, 'create-component');
|
|
1297
1327
|
let targetFolder = ensureFolderExists(sourceFolder, 'components');
|
|
1298
1328
|
let { hyphenName, camelCaseName, underscoreName } = setNameVariables(name);
|
|
1299
1329
|
//copy default shape file
|
|
1300
1330
|
log("Creating files for component '" + name + "'");
|
|
1301
1331
|
let targetFile = path.join(targetFolder, hyphenName + '.tsx');
|
|
1302
|
-
fs.copySync(
|
|
1332
|
+
fs.copySync(defaultsDir('component.tsx'), targetFile);
|
|
1303
1333
|
let targetFile2 = path.join(targetFolder, hyphenName + '.scss');
|
|
1304
|
-
fs.copySync(
|
|
1334
|
+
fs.copySync(defaultsDir('component.scss'), targetFile2);
|
|
1305
1335
|
//replace variables in some of the copied files
|
|
1306
1336
|
yield replaceVariablesInFiles(targetFile, targetFile2);
|
|
1307
1337
|
log(`Created a new component template in ${chalk.magenta(targetFile.replace(basePath, ''))}`, `Created component stylesheet template in ${chalk.magenta(targetFile2.replace(basePath, ''))}`);
|
|
@@ -1839,95 +1869,216 @@ export const createPackage = (name_1, uriBase_1, ...args_1) => __awaiter(void 0,
|
|
|
1839
1869
|
console.warn('Please provide a name as the first argument');
|
|
1840
1870
|
return;
|
|
1841
1871
|
}
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1872
|
+
const isTTY = !!(process.stdin.isTTY && process.stdout.isTTY);
|
|
1873
|
+
// What, then where. Both are settled before anything is written, so a
|
|
1874
|
+
// refusal leaves nothing behind and `both` asks each question once.
|
|
1875
|
+
const kindDecided = decidePackageKind({
|
|
1876
|
+
kind: options.kind,
|
|
1877
|
+
remote: options.remote,
|
|
1878
|
+
isTTY,
|
|
1847
1879
|
});
|
|
1880
|
+
if (kindDecided.kind === 'refuse')
|
|
1881
|
+
throw new CreatePackageError(kindDecided.message);
|
|
1882
|
+
const packageKind = kindDecided.kind === 'ask' ? yield askPackageKind(name) : kindDecided.packageKind;
|
|
1883
|
+
const appRoot = findLinkedAppRoot(basePath);
|
|
1884
|
+
const decided = decideCreatePackageTarget({ appRoot, options, isTTY });
|
|
1848
1885
|
if (decided.kind === 'refuse')
|
|
1849
1886
|
throw new CreatePackageError(decided.message);
|
|
1887
|
+
// The root its IRIs are minted under: a malformed one is refused here, before
|
|
1888
|
+
// anything is written or asked.
|
|
1889
|
+
let root;
|
|
1890
|
+
try {
|
|
1891
|
+
root = resolvePackageBaseUri({ flag: options.baseUri, appRoot });
|
|
1892
|
+
}
|
|
1893
|
+
catch (e) {
|
|
1894
|
+
throw new CreatePackageError(e.message);
|
|
1895
|
+
}
|
|
1850
1896
|
const decision = decided.kind === 'ask' ? yield askPackageLocation(name) : decided;
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1897
|
+
const packages = scaffoldKinds(packageKind).map((kind) => ({
|
|
1898
|
+
kind,
|
|
1899
|
+
name: packageNameFor(name, kind),
|
|
1900
|
+
}));
|
|
1901
|
+
// Nothing is written until every target is free.
|
|
1902
|
+
const targets = yield Promise.all(packages.map((_a) => __awaiter(void 0, [_a], void 0, function* ({ name: packageName }) {
|
|
1903
|
+
const targetFolder = yield packageTargetFolder(packageName, basePath, appRoot, decision);
|
|
1904
|
+
if (fs.existsSync(targetFolder)) {
|
|
1905
|
+
throw new CreatePackageError(`${targetFolder} already exists. Refusing to write a new package over it.`);
|
|
1906
|
+
}
|
|
1907
|
+
return targetFolder;
|
|
1908
|
+
})));
|
|
1909
|
+
// linked.cm is the normal root for an open-source package, so its absence is
|
|
1910
|
+
// information, not a warning.
|
|
1911
|
+
log(root
|
|
1912
|
+
? `Base URI ${root.baseUri} (from ${root.source}): shapes mint ${root.baseUri}shape/<package>/<Name>`
|
|
1913
|
+
: `Shapes and terms in ${packages.map((p) => p.name).join(' and ')} mint under https://linked.cm/. ` +
|
|
1914
|
+
`They resolve once the package is published (npx linked publish, coming soon).`);
|
|
1915
|
+
for (const [i, { kind, name: packageName }] of packages.entries()) {
|
|
1916
|
+
const targetFolder = targets[i];
|
|
1917
|
+
yield scaffoldPackage(packageName, kind, targetFolder, uriBase, root === null || root === void 0 ? void 0 : root.baseUri);
|
|
1918
|
+
if (kind === 'assets' && packageKind === 'both') {
|
|
1919
|
+
// The pair is one unit: the asset package's shapes use the ontology
|
|
1920
|
+
// created with it. `ontology` comes first in `scaffoldKinds`, so its
|
|
1921
|
+
// package.json is already written.
|
|
1922
|
+
const ontIndex = packages.findIndex((p) => p.kind === 'ontology');
|
|
1923
|
+
dependOnOntologyPackage(targetFolder, packages[ontIndex].name, targets[ontIndex], decision.kind === 'resolved' && decision.location === 'packages');
|
|
1924
|
+
}
|
|
1925
|
+
const skipped = () => log(`Prepared a new linked package in ${chalk.magenta(targetFolder)} (install skipped)`);
|
|
1926
|
+
if (decision.kind === 'outside') {
|
|
1927
|
+
if (options.skipInstall)
|
|
1928
|
+
skipped();
|
|
1929
|
+
else
|
|
1930
|
+
yield installStandalonePackage(targetFolder);
|
|
1931
|
+
}
|
|
1932
|
+
else if (decision.location === 'packages') {
|
|
1933
|
+
// The app's package.json is wired either way: that is files, not install.
|
|
1934
|
+
yield installWorkspacePackage(packageName, targetFolder, appRoot, options.skipInstall);
|
|
1935
|
+
}
|
|
1936
|
+
else if (options.skipInstall) {
|
|
1937
|
+
skipped();
|
|
1859
1938
|
}
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
basePath = path.join(basePath, 'modules');
|
|
1939
|
+
else {
|
|
1940
|
+
yield installOwnRepoPackage(packageName, targetFolder, appRoot, decision);
|
|
1863
1941
|
}
|
|
1864
|
-
targetFolder = path.join(basePath, cleanPackageName);
|
|
1865
1942
|
}
|
|
1866
|
-
|
|
1867
|
-
|
|
1943
|
+
});
|
|
1944
|
+
/**
|
|
1945
|
+
* Declare the ontology package as a regular dependency of the asset package,
|
|
1946
|
+
* at `^` its version — the same entry Create Now's project scaffold writes.
|
|
1947
|
+
*
|
|
1948
|
+
* Only where npm workspaces link the two (`--location packages`). Anywhere
|
|
1949
|
+
* else the `-ont` package is not published yet, so `npm install` in the asset
|
|
1950
|
+
* package would fail with E404: the entry is left out and one line says how to
|
|
1951
|
+
* add it once the ontology package is published.
|
|
1952
|
+
*/
|
|
1953
|
+
function dependOnOntologyPackage(assetsFolder, ontName, ontFolder, linkedByWorkspace) {
|
|
1954
|
+
if (!linkedByWorkspace) {
|
|
1955
|
+
log(`The asset package does not depend on ${ontName} yet: once ${ontName} is published, ` +
|
|
1956
|
+
`run npm install ${ontName} in ${assetsFolder}`);
|
|
1957
|
+
return;
|
|
1868
1958
|
}
|
|
1869
|
-
|
|
1959
|
+
const { version } = fs.readJsonSync(path.join(ontFolder, 'package.json'));
|
|
1960
|
+
const pkgPath = path.join(assetsFolder, 'package.json');
|
|
1961
|
+
const pkg = fs.readJsonSync(pkgPath);
|
|
1962
|
+
pkg.dependencies = Object.assign(Object.assign({}, pkg.dependencies), { [ontName]: `^${version}` });
|
|
1963
|
+
fs.writeJsonSync(pkgPath, pkg, { spaces: 2 });
|
|
1964
|
+
}
|
|
1965
|
+
/** Where a package goes, given where create-package was told to put it. */
|
|
1966
|
+
function packageTargetFolder(name, basePath, appRoot, decision) {
|
|
1967
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1968
|
+
//let's remove scope for folder names
|
|
1969
|
+
const cleanPackageName = bareName(name);
|
|
1970
|
+
if (decision.kind === 'outside') {
|
|
1971
|
+
//if ran with npx, basePath will be the root directory of the repository, even if we're executing from a sub folder (the root directory is where node_modules lives and package.json with workspaces)
|
|
1972
|
+
//so we manually find a packages folder, if it exists we go into that.
|
|
1973
|
+
if (fs.existsSync(path.join(basePath, 'packages'))) {
|
|
1974
|
+
basePath = path.join(basePath, 'packages');
|
|
1975
|
+
}
|
|
1976
|
+
//for lincd.org currently packages are stored in the modules folder
|
|
1977
|
+
else if (fs.existsSync(path.join(basePath, 'modules'))) {
|
|
1978
|
+
basePath = path.join(basePath, 'modules');
|
|
1979
|
+
}
|
|
1980
|
+
return path.join(basePath, cleanPackageName);
|
|
1981
|
+
}
|
|
1982
|
+
if (decision.kind === 'resolved' && decision.location === 'packages') {
|
|
1983
|
+
return path.join(appRoot, 'packages', cleanPackageName);
|
|
1984
|
+
}
|
|
1870
1985
|
// localize's own naming, so `linked localize` and this command can never
|
|
1871
1986
|
// disagree about where a package lives.
|
|
1872
1987
|
const { checkoutNameFor, DEFAULT_DIR } = yield import('./localize/index.js');
|
|
1873
|
-
|
|
1874
|
-
}
|
|
1875
|
-
if (fs.existsSync(targetFolder)) {
|
|
1876
|
-
throw new CreatePackageError(`${targetFolder} already exists. Refusing to write a new package over it.`);
|
|
1877
|
-
}
|
|
1878
|
-
if (!uriBase) {
|
|
1879
|
-
uriBase = defaultOntologyNamespace(name);
|
|
1880
|
-
}
|
|
1881
|
-
setVariable('uri_base', asNamespace(uriBase));
|
|
1882
|
-
//save the full scoped package name under ${package_name}
|
|
1883
|
-
setVariable('package_name', name);
|
|
1884
|
-
//extra variable for clarity (will be same as 'name')
|
|
1885
|
-
setVariable('output_file_name', name);
|
|
1886
|
-
const { hyphenName } = setNameVariables(cleanPackageName);
|
|
1887
|
-
log("Creating new linked package '" + name + "'");
|
|
1888
|
-
fs.mkdirSync(targetFolder, { recursive: true });
|
|
1889
|
-
fs.copySync(path.join(getScriptDir(), '..', '..', 'defaults', 'package'), targetFolder);
|
|
1890
|
-
renameShippedDotfiles(targetFolder);
|
|
1891
|
-
//replace variables in some of the copied files
|
|
1892
|
-
yield Promise.all([
|
|
1893
|
-
'src/index.ts',
|
|
1894
|
-
'package.json',
|
|
1895
|
-
'src/package.ts',
|
|
1896
|
-
'src/ontologies/example-ontology.ts',
|
|
1897
|
-
'src/ontologies/example-ontology.register.ts',
|
|
1898
|
-
'src/data/example-ontology.json',
|
|
1899
|
-
]
|
|
1900
|
-
.map((f) => path.join(targetFolder, f))
|
|
1901
|
-
.map((file) => {
|
|
1902
|
-
return replaceVariablesInFile(file);
|
|
1903
|
-
}));
|
|
1904
|
-
//rename these to a file name similar to the pkg name
|
|
1905
|
-
[
|
|
1906
|
-
'src/ontologies/example-ontology.ts',
|
|
1907
|
-
// The register sibling is what index.ts imports; without it here the scaffold keeps a
|
|
1908
|
-
// literal `example-ontology.register.ts` full of unsubstituted `${...}` placeholders and
|
|
1909
|
-
// nothing ever calls linkedOntology().
|
|
1910
|
-
'src/ontologies/example-ontology.register.ts',
|
|
1911
|
-
'src/data/example-ontology.json',
|
|
1912
|
-
'src/data/example-ontology.json.d.ts',
|
|
1913
|
-
].forEach((f) => {
|
|
1914
|
-
let parts = f.split('/');
|
|
1915
|
-
let newParts = [...parts];
|
|
1916
|
-
let [name, ...extensions] = newParts.pop().split('.');
|
|
1917
|
-
let newName = hyphenName + '.' + extensions.join('.');
|
|
1918
|
-
console.log('rename ', path.join(targetFolder, f), path.join(targetFolder, ...newParts, newName));
|
|
1919
|
-
fs.renameSync(path.join(targetFolder, f), path.join(targetFolder, ...newParts, newName));
|
|
1988
|
+
return path.join(appRoot, DEFAULT_DIR, checkoutNameFor(name));
|
|
1920
1989
|
});
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1990
|
+
}
|
|
1991
|
+
/**
|
|
1992
|
+
* Write one package of a kind. Every kind gets the shared files of
|
|
1993
|
+
* `defaults/package` (manifest, tsconfigs, dotfiles, `src/package.ts`); an asset
|
|
1994
|
+
* package gets the rest of that folder, an ontology package gets
|
|
1995
|
+
* `defaults/package-ontology` instead, with the example ontology named after
|
|
1996
|
+
* its ontology slug.
|
|
1997
|
+
*/
|
|
1998
|
+
function scaffoldPackage(name, kind, targetFolder, uriBase, baseUri) {
|
|
1999
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2000
|
+
// An ontology package `foo-ont` holds the ontology `foo`: that slug names its
|
|
2001
|
+
// files and its prefix, and its terms mint `{root}ont/foo/{Term}`.
|
|
2002
|
+
const ontologySlug = kind === 'ontology' ? ontologySlugFor(name) : undefined;
|
|
2003
|
+
if (!uriBase) {
|
|
2004
|
+
uriBase = baseUri
|
|
2005
|
+
? `${baseUri}ont/${ontologySlug !== null && ontologySlug !== void 0 ? ontologySlug : bareName(name)}/`
|
|
2006
|
+
: defaultOntologyNamespace(ontologySlug !== null && ontologySlug !== void 0 ? ontologySlug : name);
|
|
2007
|
+
}
|
|
2008
|
+
setVariable('uri_base', asNamespace(uriBase));
|
|
2009
|
+
//save the full scoped package name under ${package_name}
|
|
2010
|
+
setVariable('package_name', name);
|
|
2011
|
+
//extra variable for clarity (will be same as 'name')
|
|
2012
|
+
setVariable('output_file_name', name);
|
|
2013
|
+
const { hyphenName } = setNameVariables(ontologySlug !== null && ontologySlug !== void 0 ? ontologySlug : bareName(name));
|
|
2014
|
+
log(`Creating new linked ${kind} package '${name}'`);
|
|
2015
|
+
fs.mkdirSync(targetFolder, { recursive: true });
|
|
2016
|
+
const [shared, ...variants] = PACKAGE_TEMPLATE_DIRS[kind];
|
|
2017
|
+
if (variants.length === 0) {
|
|
2018
|
+
fs.copySync(defaultsDir(shared), targetFolder);
|
|
2019
|
+
}
|
|
2020
|
+
else {
|
|
2021
|
+
for (const file of SHARED_TEMPLATE_FILES) {
|
|
2022
|
+
fs.copySync(defaultsDir(shared, file), path.join(targetFolder, file));
|
|
2023
|
+
}
|
|
2024
|
+
for (const variant of variants) {
|
|
2025
|
+
fs.copySync(defaultsDir(variant), targetFolder);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
renameShippedDotfiles(targetFolder);
|
|
2029
|
+
//replace variables in some of the copied files
|
|
2030
|
+
yield Promise.all(['src/index.ts', 'package.json', 'src/package.ts']
|
|
2031
|
+
.concat(kind === 'ontology'
|
|
2032
|
+
? [
|
|
2033
|
+
'src/ontologies/example-ontology.ts',
|
|
2034
|
+
'src/ontologies/example-ontology.register.ts',
|
|
2035
|
+
'src/data/example-ontology.json',
|
|
2036
|
+
]
|
|
2037
|
+
: [])
|
|
2038
|
+
.map((f) => path.join(targetFolder, f))
|
|
2039
|
+
.map((file) => replaceVariablesInFile(file)));
|
|
2040
|
+
if (baseUri) {
|
|
2041
|
+
const packageTs = path.join(targetFolder, 'src', 'package.ts');
|
|
2042
|
+
fs.writeFileSync(packageTs, withBaseUri(fs.readFileSync(packageTs, 'utf8'), baseUri));
|
|
2043
|
+
}
|
|
2044
|
+
if (kind !== 'ontology')
|
|
2045
|
+
return;
|
|
2046
|
+
//rename these to a file name similar to the ontology slug
|
|
2047
|
+
[
|
|
2048
|
+
'src/ontologies/example-ontology.ts',
|
|
2049
|
+
// The register sibling is what index.ts imports; without it here the scaffold keeps a
|
|
2050
|
+
// literal `example-ontology.register.ts` full of unsubstituted `${...}` placeholders and
|
|
2051
|
+
// nothing ever calls linkedOntology().
|
|
2052
|
+
'src/ontologies/example-ontology.register.ts',
|
|
2053
|
+
'src/data/example-ontology.json',
|
|
2054
|
+
'src/data/example-ontology.json.d.ts',
|
|
2055
|
+
].forEach((f) => {
|
|
2056
|
+
let parts = f.split('/');
|
|
2057
|
+
let newParts = [...parts];
|
|
2058
|
+
let [, ...extensions] = newParts.pop().split('.');
|
|
2059
|
+
let newName = hyphenName + '.' + extensions.join('.');
|
|
2060
|
+
fs.renameSync(path.join(targetFolder, f), path.join(targetFolder, ...newParts, newName));
|
|
2061
|
+
});
|
|
2062
|
+
});
|
|
2063
|
+
}
|
|
2064
|
+
/**
|
|
2065
|
+
* Ask what kind of package to make — only ever on a terminal, and only when
|
|
2066
|
+
* `--kind` did not say.
|
|
2067
|
+
*/
|
|
2068
|
+
function askPackageKind(name) {
|
|
2069
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2070
|
+
console.log(`\nWhat kind of package is ${chalk.magenta(name)}?\n` +
|
|
2071
|
+
` 1) ontology one ontology, no shapes or components (${packageNameFor(name, 'ontology')})\n` +
|
|
2072
|
+
` 2) assets shapes, components and a backend (${packageNameFor(name, 'assets')})\n` +
|
|
2073
|
+
` 3) both the two packages above\n`);
|
|
2074
|
+
const kinds = ['ontology', 'assets', 'both'];
|
|
2075
|
+
let answer = '';
|
|
2076
|
+
while (!['1', '2', '3'].includes(answer)) {
|
|
2077
|
+
answer = yield promptUser('Choose 1, 2 or 3: ');
|
|
2078
|
+
}
|
|
2079
|
+
return kinds[Number(answer) - 1];
|
|
2080
|
+
});
|
|
2081
|
+
}
|
|
1931
2082
|
/**
|
|
1932
2083
|
* Ask where a new package goes — only ever on a terminal, and only when no
|
|
1933
2084
|
* flag said so already.
|
|
@@ -2004,8 +2155,8 @@ function installStandalonePackage(targetFolder) {
|
|
|
2004
2155
|
* workspace member by name, and `build-all` builds what the app depends on —
|
|
2005
2156
|
* and the install runs at the app root, where the workspace is.
|
|
2006
2157
|
*/
|
|
2007
|
-
function installWorkspacePackage(
|
|
2008
|
-
return __awaiter(this,
|
|
2158
|
+
function installWorkspacePackage(name_1, targetFolder_1, appRoot_1) {
|
|
2159
|
+
return __awaiter(this, arguments, void 0, function* (name, targetFolder, appRoot, skipInstall = false) {
|
|
2009
2160
|
const appPkgPath = path.join(appRoot, 'package.json');
|
|
2010
2161
|
const appPkg = fs.readJsonSync(appPkgPath);
|
|
2011
2162
|
const workspaces = ensureWorkspaceGlob(appPkg);
|
|
@@ -2016,6 +2167,10 @@ function installWorkspacePackage(name, targetFolder, appRoot) {
|
|
|
2016
2167
|
fs.writeJsonSync(appPkgPath, appPkg, { spaces: 2 });
|
|
2017
2168
|
log(`Added ${name}@^${version} to ${path.relative(process.cwd(), appPkgPath) || 'package.json'}` +
|
|
2018
2169
|
(workspaces.changed ? ' and packages/* to its workspaces' : ''));
|
|
2170
|
+
if (skipInstall) {
|
|
2171
|
+
log(`Prepared a new linked package in ${chalk.magenta(targetFolder)} (install skipped)`);
|
|
2172
|
+
return;
|
|
2173
|
+
}
|
|
2019
2174
|
const setup = yield packageSetupFor(appRoot);
|
|
2020
2175
|
yield installThenBuild(setup, appRoot, targetFolder, `The app's package.json already declares ${name}; run the install again at the app root once it is fixed.`);
|
|
2021
2176
|
log(`Prepared a new linked package in ${chalk.magenta(targetFolder)}, part of this app's repository`, `Run ${chalk.blueBright(runScriptCommand(setup.packageManager, 'start'))} in it to continuously rebuild on file changes`);
|