@_linked/cli 1.6.4 → 1.8.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-loader.d.mts","sourceRoot":"","sources":["../../../src/loaders/ts-loader.mts"],"names":[],"mappings":"AAsCA,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,GAAG,EACZ,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GAC7D,OAAO,CAAC,GAAG,CAAC,CA0Dd;AAED,wBAAsB,IAAI,CACxB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,GAAG,EACZ,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GACpD,OAAO,CAAC,GAAG,CAAC,CAwBd"}
@@ -0,0 +1,116 @@
1
+ var _a;
2
+ // Node ESM loader for .ts / .tsx / .mts / .cts. Transforms via esbuild
3
+ // with `experimentalDecorators: true` forced on — @_linked/core's
4
+ // @literalProperty / @objectProperty / @linkedShape ship the legacy
5
+ // signature `(target, propertyKey, descriptor)`, so the loader has to
6
+ // produce legacy `__decorate(...)` calls. tsx (which we previously
7
+ // relied on) ignores experimentalDecorators since esbuild's default
8
+ // follows the TC39 standard decorator proposal — that mismatch silently
9
+ // broke decorator-based property registration in user scripts.
10
+ import { readFileSync, existsSync, statSync } from 'node:fs';
11
+ import { fileURLToPath, pathToFileURL } from 'node:url';
12
+ import path from 'node:path';
13
+ import { transformSync } from 'esbuild';
14
+ // Read the user's tsconfig once at boot. We re-use it for every TS file
15
+ // we transform so a single source of truth (the user app's tsconfig)
16
+ // drives target / jsx / paths / etc.
17
+ const userTsconfigPath = path.join(process.cwd(), 'tsconfig.json');
18
+ let userTsconfigRaw = { compilerOptions: {} };
19
+ if (existsSync(userTsconfigPath)) {
20
+ try {
21
+ userTsconfigRaw = JSON.parse(readFileSync(userTsconfigPath, 'utf8'));
22
+ userTsconfigRaw.compilerOptions = (_a = userTsconfigRaw.compilerOptions) !== null && _a !== void 0 ? _a : {};
23
+ }
24
+ catch (_b) {
25
+ // Fall back to empty config if parsing fails — esbuild still works.
26
+ }
27
+ }
28
+ // Force legacy decorator emit regardless of what the user's tsconfig says.
29
+ userTsconfigRaw.compilerOptions.experimentalDecorators = true;
30
+ const tsconfigRaw = JSON.stringify(userTsconfigRaw);
31
+ const TS_EXT = /\.(tsx?|mts|cts)$/;
32
+ const TS_RESOLUTION_EXTS = ['.ts', '.tsx', '.mts', '.cts'];
33
+ // Node's default ESM resolver requires explicit extensions on relative
34
+ // specifiers. App code (and the cli's user-app imports) routinely omits
35
+ // them — tsx used to backfill this, so we have to as well. We only
36
+ // touch `./foo` / `../foo` style imports; bare specifiers go straight to
37
+ // Node's resolver.
38
+ export async function resolve(specifier, context, nextResolve) {
39
+ // Direct .ts/.tsx/.mts/.cts specifier (relative or absolute path).
40
+ // Node's default ESM resolver doesn't accept these extensions, so we
41
+ // short-circuit and let our `load` hook do the transform.
42
+ if (TS_EXT.test(specifier)) {
43
+ if (specifier.startsWith('file://')) {
44
+ return { url: specifier, shortCircuit: true, format: 'module' };
45
+ }
46
+ if (path.isAbsolute(specifier)) {
47
+ return {
48
+ url: pathToFileURL(specifier).href,
49
+ shortCircuit: true,
50
+ format: 'module',
51
+ };
52
+ }
53
+ if (specifier.startsWith('./') || specifier.startsWith('../')) {
54
+ const parentUrl = context.parentURL;
55
+ if (parentUrl) {
56
+ const parentPath = fileURLToPath(parentUrl);
57
+ const resolved = path.resolve(path.dirname(parentPath), specifier);
58
+ return {
59
+ url: pathToFileURL(resolved).href,
60
+ shortCircuit: true,
61
+ format: 'module',
62
+ };
63
+ }
64
+ }
65
+ }
66
+ // Extension-less relative specifier — backfill the extension by probing
67
+ // the disk. App code routinely omits `.ts`/`.tsx` on intra-app imports.
68
+ if ((specifier.startsWith('./') || specifier.startsWith('../')) &&
69
+ !path.extname(specifier)) {
70
+ const parentUrl = context.parentURL;
71
+ if (parentUrl) {
72
+ const parentPath = fileURLToPath(parentUrl);
73
+ const resolvedBase = path.resolve(path.dirname(parentPath), specifier);
74
+ const candidates = [
75
+ ...TS_RESOLUTION_EXTS.map((ext) => resolvedBase + ext),
76
+ ...TS_RESOLUTION_EXTS.map((ext) => path.join(resolvedBase, 'index' + ext)),
77
+ ];
78
+ for (const candidate of candidates) {
79
+ if (existsSync(candidate) && statSync(candidate).isFile()) {
80
+ return {
81
+ url: pathToFileURL(candidate).href,
82
+ shortCircuit: true,
83
+ format: 'module',
84
+ };
85
+ }
86
+ }
87
+ }
88
+ }
89
+ return nextResolve(specifier, context);
90
+ }
91
+ export async function load(url, context, nextLoad) {
92
+ if (!TS_EXT.test(url)) {
93
+ return nextLoad(url, context);
94
+ }
95
+ const filePath = fileURLToPath(url);
96
+ const source = readFileSync(filePath, 'utf8');
97
+ const isTsx = url.endsWith('.tsx');
98
+ const { code } = transformSync(source, {
99
+ loader: isTsx ? 'tsx' : 'ts',
100
+ format: 'esm',
101
+ target: 'es2022',
102
+ sourcefile: filePath,
103
+ sourcemap: 'inline',
104
+ tsconfigRaw,
105
+ // Keep `import x from './data.json' with { type: 'json' }` syntax in
106
+ // the output — Node 22+ requires the attribute on JSON imports and
107
+ // esbuild strips it by default when downleveling below esnext.
108
+ supported: { 'import-attributes': true },
109
+ });
110
+ return {
111
+ format: 'module',
112
+ source: code,
113
+ shortCircuit: true,
114
+ };
115
+ }
116
+ //# sourceMappingURL=ts-loader.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-loader.mjs","sourceRoot":"","sources":["../../../src/loaders/ts-loader.mts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@_linked/cli",
3
- "version": "1.6.4",
3
+ "version": "1.8.0",
4
4
  "description": "Command line tools for the @_linked/* packages and apps",
5
5
  "typesVersions": {
6
6
  "*": {
@@ -80,6 +80,7 @@
80
80
  "cssnano": "^7.0.7",
81
81
  "depcheck": "^1.4.7",
82
82
  "env-cmd": "^10.1.0",
83
+ "esbuild": "^0.28.0",
83
84
  "find-nearest-package-json": "^2.0.1",
84
85
  "fs-extra": "^11.2.0",
85
86
  "glob": "^10.3.12",
@@ -1 +1 @@
1
- {"version":3,"file":"cli-methods.d.ts","sourceRoot":"","sources":["../../src/cli-methods.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-methods.d.ts","sourceRoot":"","sources":["../../src/cli-methods.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAC,cAAc,EAAC,MAAM,cAAc,CAAC;AAoE5C,eAAO,MAAM,SAAS,GAAU,SAAI,EAAE,iBAAwB,EAAE,UAAS;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAM,kBAgL9J,CAAC;AAmBF,wBAAgB,IAAI,CAAC,GAAG,QAAQ,OAAA,QAK/B;AACD,wBAAgB,QAAQ,CAAC,GAAG,MAAM,OAAA,QAIjC;AACD,wBAAgB,cAAc,CAAC,MAAM,KAAA,EAAE,IAAI,KAAA,QAyB1C;AA2CD,wBAAgB,kCAAkC,CAChD,aAAa,KAAA,EACb,YAAY,EAAE,CACZ,YAAY,KAAA,EACZ,YAAY,KAAA,KACT,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,GAAG,CAAC,EAC1C,UAAU,KAAA,EACV,IAAI,UAAQ,GACX,OAAO,CAAC,IAAI,CAAC,CAqNf;AA+ID,wBAAgB,QAAQ,CAAC,OAAO,KAAA,QAkU/B;AAkCD,wBAAgB,gBAAgB,CAAC,QAAQ,SAAgB,GAAG,cAAc,EAAE,CAyB3E;AAyCD,eAAO,MAAM,cAAc,GACzB,WAAM,EACN,aAAQ,EACR,iBAAwB,kBA6FzB,CAAC;AAuIF,eAAO,MAAM,gBAAgB,GAAa,SAAI;;;;;CAc7C,CAAC;AAgBF;;GAEG;AACH,eAAO,MAAM,YAAY,cAaxB,CAAC;AACF,eAAO,MAAM,WAAW,GAAU,SAAI,EAAE,iBAAwB,kBA2B/D,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,SAAI,EAAE,iBAAwB,kBAmCtE,CAAC;AACF,eAAO,MAAM,eAAe,GAAU,SAAI,EAAE,iBAAwB,kBAuCnE,CAAC;AAKF,eAAO,MAAM,YAAY,GACvB,eAAc,MAA0B,EACxC,QAAO,MAAU,EAAE,wDAAwD;AAC3E,iBAAgB,GAAG,CAAC,MAAM,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,EAAE,CAAa,qBA4F9E,CAAC;AAEF,eAAO,MAAM,cAAc,qBAuB1B,CAAC;AACF,eAAO,MAAM,QAAQ,GAAU,cAAa,MAAsB,qBAwDjE,CAAC;AACF,eAAO,MAAM,uBAAuB,qBAoDnC,CAAC;AACF,eAAO,MAAM,SAAS,GACpB,YAAY,MAAM,EAClB,SAAS;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,mBAoB1B,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,aAAa,MAAM,EACnB,QAAQ,MAAM,EACd,SAAS;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,kBA2G1B,CAAC;AACF,eAAO,MAAM,WAAW,GACtB,WAAU,OAAe,EACzB,iBAAkB,iBA8DnB,CAAC;AACF,eAAO,MAAM,QAAQ,sBAKpB,CAAC;AACF,eAAO,MAAM,aAAa,qBAiHzB,CAAC;AACF,eAAO,MAAM,YAAY,wBAiExB,CAAC;AAEF,eAAO,MAAM,eAAe,qBAoK3B,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,SAAI,EACJ,aAAQ,EACR,iBAAwB,kBA4GzB,CAAC;AAqBF,eAAO,MAAM,QAAQ,GAAa,gBAAW,kBAuD5C,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,WAAM,EACN,YAAO,EACP,oBAA2B,EAC3B,aAAY,OAAc,iBAoN3B,CAAC;AACF,eAAO,MAAM,cAAc,GAAU,oBAA2B,kBAyB/D,CAAC;AACF,eAAO,MAAM,iBAAiB,GAAU,oBAA2B,qBAWlE,CAAC;AACF,eAAO,MAAM,iBAAiB,GAAU,oBAA2B;;EAelE,CAAC;AAEF,eAAO,IAAI,cAAc,GAAa,OAAM,OAAe,kBA0K1D,CAAC;AAsBF,eAAO,IAAI,cAAc,GACvB,SAAI,EACJ,UAAK,EACL,UAAK,EACL,oBAAe,oBA6DhB,CAAC;AAEF,eAAO,IAAI,YAAY,GACrB,SAAI,EACJ,WAAM,EACN,YAAO,EACP,wBAAuB,OAAe,EACtC,OAAM,OAAe,kBAqHtB,CAAC;AAeF,eAAO,IAAI,4BAA4B,GACrC,aAAQ,EACR,YAAO,EACP,iBAAY,EACZ,gBAAW,qBA4CZ,CAAC;AAOF,eAAO,IAAI,cAAc,GAAa,aAAQ,EAAE,YAAO,SAMtD,CAAC;AACF,eAAO,IAAI,YAAY,GAAmB,iBAAwB,kBA8FjE,CAAC;AAEF,eAAO,IAAI,wBAAwB,GAAa,gBAAW,EAAE,YAAO,SA6BnE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAU,gBAAW,qBA8B/C,CAAC"}
@@ -131,6 +131,15 @@ export const createApp = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...ar
131
131
  });
132
132
  fs.renameSync(path.join(targetFolder, 'gitignore.template'), path.join(targetFolder, '.gitignore'));
133
133
  fs.renameSync(path.join(targetFolder, 'yarnrc.yml.template'), path.join(targetFolder, '.yarnrc.yml'));
134
+ // Mark the new app as a self-contained Yarn project root. Without this,
135
+ // Yarn climbs ancestor dirs looking for the project root and may decide
136
+ // a stray yarn.lock further up the tree is "the project" — aborting
137
+ // install with "the nearest package directory doesn't seem to be part
138
+ // of the project declared in <ancestor>".
139
+ const yarnLockPath = path.join(targetFolder, 'yarn.lock');
140
+ if (!fs.existsSync(yarnLockPath)) {
141
+ fs.writeFileSync(yarnLockPath, '');
142
+ }
134
143
  // Seed the real (gitignored) Layer 2 config from the committed example so
135
144
  // the scaffolded app boots first try. Users can edit either file later.
136
145
  const datasetsExample = path.join(targetFolder, 'linked.backend.datasets.example.json');
@@ -142,13 +151,19 @@ export const createApp = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...ar
142
151
  log("Creating new Linked app '" + appName + "'");
143
152
  //replace variables in some copied files
144
153
  yield replaceVariablesInFolder(targetFolder);
154
+ // Pick a package manager. When both are available and the user is running
155
+ // create-app interactively, ask. Carry the choice through both the install
156
+ // step AND the final "next command" message so the user can copy-paste.
157
+ const interactive = !(options.appName ||
158
+ options.appPrefix ||
159
+ options.appDomain);
160
+ const pm = yield choosePackageManager(interactive);
145
161
  if (!options.skipInstall) {
146
- let hasYarn = yield hasYarnInstalled();
147
- let installCommand = hasYarn
162
+ const installCommand = pm === 'yarn'
148
163
  ? 'export NODE_OPTIONS="--no-network-family-autoselection" && yarn install'
149
164
  : 'npm install';
150
165
  const spinner = ora({
151
- text: `Installing dependencies (${hasYarn ? 'yarn' : 'npm'})...`,
166
+ text: `Installing dependencies (${pm})...`,
152
167
  spinner: 'dots',
153
168
  }).start();
154
169
  const { stdout, stderr, failed } = yield new Promise((resolve) => {
@@ -169,7 +184,7 @@ export const createApp = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...ar
169
184
  process.stderr.write(stderr);
170
185
  }
171
186
  else {
172
- spinner.succeed(`Dependencies installed (${hasYarn ? 'yarn' : 'npm'})`);
187
+ spinner.succeed(`Dependencies installed (${pm})`);
173
188
  // Even on a 0-exit install, surface stderr (peer-dep warnings,
174
189
  // deprecations, ERESOLVE warns). Silent installs hide real problems
175
190
  // that bite users the next time they touch the lockfile.
@@ -178,7 +193,8 @@ export const createApp = (name_1, ...args_1) => __awaiter(void 0, [name_1, ...ar
178
193
  }
179
194
  }
180
195
  }
181
- 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 (with npm or yarn):`, ` ${chalk.blueBright(`cd ${hyphenName} && npm start`)}`, ` ${chalk.gray('# or: yarn start')}`);
196
+ const startCommand = pm === 'yarn' ? 'yarn start' : 'npm start';
197
+ 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}`)}`);
182
198
  });
183
199
  function logHelp() {
184
200
  execp('yarn exec lincd help');
@@ -968,15 +984,49 @@ const replaceVariablesInFolder = function (folder) {
968
984
  const replaceVariablesInFilesWithRoot = function (root, ...files) {
969
985
  return replaceVariablesInFiles(...files.map((f) => path.join(root, f)));
970
986
  };
971
- const hasYarnInstalled = function () {
987
+ function isAvailable(cmd) {
972
988
  return __awaiter(this, void 0, void 0, function* () {
973
- let version = (yield execPromise('yarn --version').catch((err) => {
974
- console.log('yarn probably not working');
975
- return '';
976
- }));
977
- return version.toString().match(/[0-9]+/);
989
+ try {
990
+ const out = (yield execPromise(`${cmd} --version`, false, false));
991
+ return /\d+/.test(String(out));
992
+ }
993
+ catch (_a) {
994
+ return false;
995
+ }
978
996
  });
979
- };
997
+ }
998
+ function detectPackageManagers() {
999
+ return __awaiter(this, void 0, void 0, function* () {
1000
+ const found = [];
1001
+ if (yield isAvailable('npm'))
1002
+ found.push('npm');
1003
+ if (yield isAvailable('yarn'))
1004
+ found.push('yarn');
1005
+ return found;
1006
+ });
1007
+ }
1008
+ function choosePackageManager(interactive) {
1009
+ return __awaiter(this, void 0, void 0, function* () {
1010
+ const available = yield detectPackageManagers();
1011
+ if (available.length === 0) {
1012
+ throw new Error('Neither npm nor yarn is available on PATH. Install one and retry.');
1013
+ }
1014
+ if (available.length === 1)
1015
+ return available[0];
1016
+ if (!interactive) {
1017
+ // Match the historical default: prefer yarn when both are installed.
1018
+ return available.includes('yarn') ? 'yarn' : 'npm';
1019
+ }
1020
+ const fallback = available.includes('yarn') ? 'yarn' : 'npm';
1021
+ const answer = yield promptUser(`Package manager [${available.join('/')}] (default: ${chalk.gray(fallback)}): `);
1022
+ const choice = answer.trim().toLowerCase();
1023
+ if (choice === 'npm' || choice === 'yarn') {
1024
+ if (available.includes(choice))
1025
+ return choice;
1026
+ }
1027
+ return fallback;
1028
+ });
1029
+ }
980
1030
  const ensureFolderExists = function (...folders) {
981
1031
  let target;
982
1032
  folders.forEach((folder) => {