@tinycld/bootstrap 1.0.0 → 1.1.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.
@@ -1,6 +1,8 @@
1
1
  import { spawnSync } from 'node:child_process';
2
- import { existsSync, writeFileSync } from 'node:fs';
2
+ import { existsSync, mkdtempSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
3
4
  import { join } from 'node:path';
5
+ import { looksLikeWorkspaceRoot } from "./layout.js";
4
6
  // All feature members that exist in the ecosystem. The workspace manifest lists
5
7
  // ALL of them (npm tolerates absent dirs), so a partial checkout still installs.
6
8
  // But --tooling CLONES only app+core+requested — we do NOT force-clone all.
@@ -11,35 +13,104 @@ const ALWAYS_CLONE = ['app', 'core'];
11
13
  // Listed in the manifest workspaces array (everything that could exist).
12
14
  const ALL_MEMBERS = ['app', 'core', 'package-scripts', ...ALL_FEATURES];
13
15
  /**
14
- * Write a workspace-root package.json + .npmrc into `dir`. The workspaces array
15
- * ALWAYS lists every possible member — npm ignores entries whose dirs are
16
- * absent, so a partial checkout (app+core+one feature) installs fine, and
17
- * cloning more features later needs no manifest edit.
16
+ * Write (or merge into) a workspace-root package.json + .npmrc in `dir`.
17
+ *
18
+ * When `dir/package.json` already exists (e.g. provided by the workspace clone),
19
+ * we preserve its fields and only enforce the two things bootstrap owns:
20
+ * the complete `workspaces` list (so later --with clones need no manifest edit)
21
+ * and the `postinstall` script. All other fields — devDependencies, engines,
22
+ * volta, extra scripts, etc. — survive as-is.
23
+ *
24
+ * When no package.json exists yet (workspace clone was skipped), the full
25
+ * generated defaults are written, matching the previous behaviour.
26
+ *
27
+ * The workspaces array ALWAYS lists every possible member — npm ignores entries
28
+ * whose dirs are absent, so a partial checkout installs fine.
29
+ *
30
+ * .npmrc is written only when one does not already exist, for the same reason.
18
31
  */
19
32
  export function writeWorkspaceManifest(dir) {
33
+ const pkgPath = join(dir, 'package.json');
34
+ let existing = {};
35
+ if (existsSync(pkgPath)) {
36
+ try {
37
+ existing = JSON.parse(readFileSync(pkgPath, 'utf-8'));
38
+ }
39
+ catch {
40
+ // Unparseable existing file — start from defaults
41
+ }
42
+ }
43
+ const existingScripts = typeof existing.scripts === 'object' && existing.scripts !== null
44
+ ? existing.scripts
45
+ : {};
20
46
  const pkg = {
21
47
  name: '@tinycld/workspace',
22
48
  version: '0.0.0',
23
49
  private: true,
24
50
  type: 'module',
51
+ ...existing,
52
+ // Always enforce the canonical workspaces list and postinstall script.
25
53
  workspaces: [...ALL_MEMBERS],
26
54
  scripts: {
55
+ ...existingScripts,
27
56
  postinstall: 'cd app && npm run packages:generate && npm run assets:copy-pdfjs',
28
57
  },
29
58
  };
30
- writeFileSync(join(dir, 'package.json'), `${JSON.stringify(pkg, null, 4)}\n`);
31
- writeFileSync(join(dir, '.npmrc'), 'legacy-peer-deps=true\n');
59
+ writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 4)}\n`);
60
+ const npmrcPath = join(dir, '.npmrc');
61
+ if (!existsSync(npmrcPath)) {
62
+ writeFileSync(npmrcPath, 'legacy-peer-deps=true\n');
63
+ }
32
64
  }
33
65
  function realClone(url, dest) {
34
66
  const r = spawnSync('git', ['clone', '--depth', '1', url, dest], { stdio: 'inherit' });
35
67
  return r.status === 0;
36
68
  }
37
69
  /**
38
- * Assemble a workspace skeleton at opts.root: write the (full) manifest, then
39
- * clone ONLY app + core + the explicitly-requested feature members (skipping any
40
- * already present — e.g. a CI-checked-out member). Unknown member names throw.
41
- * Returns the members that ended up present. Does NOT run npm install (the
42
- * caller / CI controls that, since it may want a clean `npm ci`).
70
+ * Clone the workspace meta-repo into `root`, tolerating a non-empty target.
71
+ *
72
+ * A plain `git clone <url> <root>` fails when `root` already contains files
73
+ * (e.g. the link-package flow pre-creates a `<slug>/` subdir there). We
74
+ * clone into a fresh sibling temp dir, then move each top-level entry into
75
+ * `root`, skipping any that already exist. The `.git` dir is moved too unless
76
+ * `root/.git` already exists.
77
+ *
78
+ * The `cloneFn` primitive is the same injected-or-real clone used for app/core —
79
+ * tests inject a stub that records URLs but does not create files, so the
80
+ * move logic will simply move nothing from an empty temp dir (which is fine
81
+ * for unit tests). Real runs move the full repo contents.
82
+ */
83
+ function cloneWorkspaceIntoRoot(url, root, cloneFn) {
84
+ const tempDir = mkdtempSync(join(tmpdir(), 'tinycld-workspace-'));
85
+ try {
86
+ if (!cloneFn(url, tempDir))
87
+ return false;
88
+ const rootHasGit = existsSync(join(root, '.git'));
89
+ for (const entry of readdirSync(tempDir)) {
90
+ // Skip .git if root already has one
91
+ if (entry === '.git' && rootHasGit)
92
+ continue;
93
+ const src = join(tempDir, entry);
94
+ const dest = join(root, entry);
95
+ // Never overwrite an entry that already exists in root
96
+ if (existsSync(dest))
97
+ continue;
98
+ renameSync(src, dest);
99
+ }
100
+ return true;
101
+ }
102
+ finally {
103
+ rmSync(tempDir, { recursive: true, force: true });
104
+ }
105
+ }
106
+ /**
107
+ * Assemble a workspace skeleton at opts.root: if root is not yet a workspace,
108
+ * clone the workspace meta-repo into it first (self-init), then write the full
109
+ * manifest, then clone ONLY app + core + the explicitly-requested feature
110
+ * members (skipping any already present — e.g. a CI-checked-out member).
111
+ * Unknown member names throw. Returns the members that ended up present. Does
112
+ * NOT run npm install (the caller / CI controls that, since it may want a
113
+ * clean `npm ci`).
43
114
  */
44
115
  export function bootstrapTooling(opts) {
45
116
  const requested = opts.members ?? [];
@@ -49,9 +120,21 @@ export function bootstrapTooling(opts) {
49
120
  }
50
121
  const repoBase = opts.repoBase ?? 'git@github.com:tinycld';
51
122
  const clone = opts.clone ?? realClone;
123
+ const present = [];
124
+ // Self-init: clone the workspace meta-repo into root if it isn't already
125
+ // a workspace root. This provides package-scripts/, tinycld.packages.ts,
126
+ // tests/, .node-version, .go-version, .npmrc, and the canonical root
127
+ // package.json before anything else runs.
128
+ if (!looksLikeWorkspaceRoot(opts.root)) {
129
+ if (cloneWorkspaceIntoRoot(`${repoBase}/workspace.git`, opts.root, clone)) {
130
+ present.push('workspace');
131
+ }
132
+ }
133
+ // Merge the canonical workspaces list + postinstall into any existing
134
+ // package.json (provided by the workspace clone), or write defaults when
135
+ // no file exists yet (workspace clone was skipped or failed).
52
136
  writeWorkspaceManifest(opts.root);
53
137
  const toClone = Array.from(new Set([...ALWAYS_CLONE, ...requested]));
54
- const present = [];
55
138
  for (const m of toClone) {
56
139
  const dest = join(opts.root, m);
57
140
  if (existsSync(join(dest, '.git')) || existsSync(join(dest, 'package.json'))) {
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap-tooling.js","sourceRoot":"","sources":["../src/bootstrap-tooling.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap-tooling.js","sourceRoot":"","sources":["../src/bootstrap-tooling.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { realpathSync } from 'node:fs';
3
- import { dirname, relative } from 'node:path';
3
+ import { dirname, join, relative } from 'node:path';
4
4
  import { pathToFileURL } from 'node:url';
5
5
  import { intro, outro } from '@clack/prompts';
6
6
  import pc from 'picocolors';
@@ -12,7 +12,14 @@ import { offerLinkPackage } from "./link-package.js";
12
12
  import { runPrompts } from "./prompts.js";
13
13
  export function runToolingMode(opts) {
14
14
  const root = opts.root ?? process.cwd();
15
- const present = bootstrapTooling({ ...opts, root });
15
+ // Honor TINYCLD_REPO_BASE (CI sets it to an HTTPS base since runners have no
16
+ // SSH key). Listed first so an explicit opts.repoBase still wins via spread;
17
+ // when neither is set, bootstrapTooling falls back to its SSH default.
18
+ const present = bootstrapTooling({
19
+ repoBase: process.env.TINYCLD_REPO_BASE,
20
+ ...opts,
21
+ root,
22
+ });
16
23
  // Mandatory members must clone — a missing app/core means a broken workspace.
17
24
  for (const required of ['app', 'core']) {
18
25
  if (!present.includes(required)) {
@@ -44,31 +51,33 @@ async function main() {
44
51
  }
45
52
  const answers = await runPrompts(args);
46
53
  copyTemplate(resolveTemplatesRoot(import.meta.url), answers);
54
+ // The package lives at `<workspaceDir>/<slug>`, so its parent is the
55
+ // workspace dir in both attach (cwd) and bootstrap (wrapper) modes.
47
56
  const linked = await offerLinkPackage({
48
- packageName: answers.slug,
49
- targetDir: answers.targetDir,
57
+ slug: answers.slug,
58
+ workspaceDir: dirname(answers.targetDir),
50
59
  mode: resolveLinkMode(args),
51
60
  });
52
61
  const relTarget = relative(process.cwd(), answers.targetDir) || answers.targetDir;
53
62
  outro(pc.green(`Scaffolded ${pc.bold(answers.slug)} at ${pc.bold(relTarget)}`));
54
63
  // Re-derive the layout from the resolved target so the next-steps output
55
64
  // matches whatever path the user actually ended up at (default detection,
56
- // explicit --target, or interactive override). The wrapper's parent dir
57
- // names where `cd ../tinycld` lands.
65
+ // explicit --target, or interactive override). It decides whether to print
66
+ // the bootstrap "self-contained workspace" note.
58
67
  const layout = detectLayoutFromTarget(answers.targetDir, answers.slug);
59
68
  printNextSteps({ slug: answers.slug, relTarget, linked, layout });
60
69
  }
61
70
  function detectLayoutFromTarget(targetDir, slug) {
62
- // If cwd has a tinycld/ child (workspace mode) and target is a sibling of
63
- // that tinycld, we're in attach mode. Otherwise the scaffolder created a
64
- // wrapper under cwd and dropped tinycld inside it (bootstrap mode).
71
+ // If cwd is itself a workspace root and target is a direct child of it,
72
+ // we're in attach mode. Otherwise the scaffolder created a wrapper under
73
+ // cwd and the workspace meta-repo gets cloned inside it (bootstrap mode).
65
74
  const detected = detectLayout(slug);
66
75
  if (detected.mode === 'attach' && targetDir === detected.targetDir)
67
76
  return 'attach';
68
77
  if (detected.mode === 'bootstrap' && targetDir === detected.targetDir)
69
78
  return 'bootstrap';
70
79
  // User passed an explicit --target. Infer from the on-disk shape: if the
71
- // parent of targetDir has a `tinycld` child, treat as attach.
80
+ // parent of targetDir is itself a workspace root, treat as attach.
72
81
  const parent = dirname(targetDir);
73
82
  const looksAttached = detectLayout(slug, parent).mode === 'attach';
74
83
  return looksAttached ? 'attach' : 'bootstrap';
@@ -85,11 +94,15 @@ function resolveLinkMode(args) {
85
94
  function printNextSteps({ slug, relTarget, linked, layout }) {
86
95
  const lines = ['', pc.bold('Next steps:'), ''];
87
96
  let step = 1;
97
+ // The workspace root, relative to cwd. In bootstrap mode the package sits at
98
+ // `<wrapper>/<slug>`, so the wrapper (`dirname(relTarget)`) is the workspace
99
+ // root. In attach mode cwd already IS the workspace root, so it's `.`.
100
+ const wsRoot = dirname(relTarget) || '.';
88
101
  if (layout === 'bootstrap') {
89
- // Highlight that the scaffolder also dropped a tinycld checkout
90
- // alongside the new package. New users may not realize they just
91
- // got a self-contained workspace.
92
- lines.push(pc.dim(` Scaffolded a self-contained workspace alongside the package.\n The tinycld app shell lives at ./${dirname(relTarget)}/tinycld/.\n`));
102
+ // The meta-repo was cloned into the wrapper, so the wrapper itself is the
103
+ // workspace root and the new package is a member directory inside it.
104
+ // New users may not realize they just got a self-contained workspace.
105
+ lines.push(pc.dim(` Scaffolded a self-contained tinycld workspace.\n The workspace root is ./${wsRoot}/ and your package is ./${relTarget}/.\n The app member (Expo + PocketBase) is ./${wsRoot}/app/.\n`));
93
106
  }
94
107
  lines.push(` ${pc.dim(`# ${step++}. Initialize git and push to GitHub`)}`);
95
108
  lines.push(` cd ${relTarget}`);
@@ -99,18 +112,24 @@ function printNextSteps({ slug, relTarget, linked, layout }) {
99
112
  lines.push(` gh repo create tinycld/${slug} --public --source=. --push`);
100
113
  lines.push('');
101
114
  if (!linked) {
102
- lines.push(` ${pc.dim(`# ${step++}. Link into the tinycld app shell`)}`);
103
- lines.push(' cd ../tinycld');
104
- lines.push(` npm run packages:link ../${slug}`);
115
+ // Linking is now a workspace-root `npm install`: the package dir already
116
+ // exists; add it to the root package.json `workspaces` if it isn't a
117
+ // member yet, then install — npm symlinks it and the postinstall runs
118
+ // the generator.
119
+ lines.push(` ${pc.dim(`# ${step++}. Link into the workspace (add as a member, then install)`)}`);
120
+ if (wsRoot !== '.')
121
+ lines.push(` cd ${wsRoot}`);
122
+ lines.push(` # ensure "${slug}" is in this package.json's "workspaces" array, then:`);
123
+ lines.push(' npm install');
105
124
  lines.push('');
106
125
  }
107
- lines.push(` ${pc.dim(`# ${step++}. Verify (biome + tsc run from the app shell and cover the linked package)`)}`);
108
- if (linked)
109
- lines.push(' cd ../tinycld');
110
- lines.push(' npm run checks');
126
+ lines.push(` ${pc.dim(`# ${step++}. Verify the package (biome + tsc, scoped to this member)`)}`);
127
+ lines.push(` cd ${join(wsRoot, slug)}`);
128
+ lines.push(' npx tinycld-pkg check');
111
129
  lines.push('');
112
130
  lines.push(` ${pc.dim(`# ${step++}. Run the app (Expo + PocketBase, single-port dev proxy)`)}`);
113
- lines.push(' npm run start');
131
+ lines.push(` cd ${join(wsRoot, 'app')}`);
132
+ lines.push(' npm run dev');
114
133
  lines.push('');
115
134
  console.log(lines.join('\n'));
116
135
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/layout.js CHANGED
@@ -1,37 +1,24 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join, resolve } from 'node:path';
3
- const APP_DIR_NAME = 'tinycld';
4
3
  export function detectLayout(slug, cwd = process.cwd()) {
5
- const candidateApp = join(cwd, APP_DIR_NAME);
6
- if (looksLikeAppShell(candidateApp)) {
7
- return {
8
- mode: 'attach',
9
- targetDir: resolve(cwd, slug),
10
- appDir: candidateApp,
11
- };
4
+ if (looksLikeWorkspaceRoot(cwd)) {
5
+ return { mode: 'attach', targetDir: resolve(cwd, slug), workspaceDir: cwd };
12
6
  }
13
- const wrapperDir = resolve(cwd, `${APP_DIR_NAME}-${slug}`);
7
+ const wrapperDir = resolve(cwd, `tinycld-${slug}`);
14
8
  return {
15
9
  mode: 'bootstrap',
16
10
  targetDir: join(wrapperDir, slug),
17
- appDir: join(wrapperDir, APP_DIR_NAME),
11
+ workspaceDir: wrapperDir,
18
12
  wrapperDir,
19
13
  };
20
14
  }
21
- /**
22
- * A directory "looks like" the tinycld app shell when it has a package.json
23
- * declaring `name: "tinycld"`. The bare directory check would false-match any
24
- * unrelated `tinycld` directory; the package.json check is fast (one read of
25
- * a file we'd be reading anyway) and unambiguous now that the app shell's
26
- * package.json `name` field has been renamed from "@tinycld/app" to "tinycld".
27
- */
28
- export function looksLikeAppShell(dir) {
15
+ /** A directory is a workspace root when its package.json name is "@tinycld/workspace". */
16
+ export function looksLikeWorkspaceRoot(dir) {
29
17
  const pkgPath = join(dir, 'package.json');
30
18
  if (!existsSync(pkgPath))
31
19
  return false;
32
20
  try {
33
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
34
- return pkg?.name === 'tinycld';
21
+ return JSON.parse(readFileSync(pkgPath, 'utf-8'))?.name === '@tinycld/workspace';
35
22
  }
36
23
  catch {
37
24
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAuBzC,MAAM,YAAY,GAAG,SAAS,CAAA;AAE9B,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,MAAc,OAAO,CAAC,GAAG,EAAE;IAClE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;IAC5C,IAAI,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;QAClC,OAAO;YACH,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC;YAC7B,MAAM,EAAE,YAAY;SACvB,CAAA;IACL,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,YAAY,IAAI,IAAI,EAAE,CAAC,CAAA;IAC1D,OAAO;QACH,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;QACjC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC;QACtC,UAAU;KACb,CAAA;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IACzC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAA;IACtC,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;QACtD,OAAO,GAAG,EAAE,IAAI,KAAK,SAAS,CAAA;IAClC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAA;IAChB,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAgBzC,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,MAAc,OAAO,CAAC,GAAG,EAAE;IAClE,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,CAAA;IAC/E,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,WAAW,IAAI,EAAE,CAAC,CAAA;IAClD,OAAO;QACH,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;QACjC,YAAY,EAAE,UAAU;QACxB,UAAU;KACb,CAAA;AACL,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IACzC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAA;IACtC,IAAI,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,IAAI,KAAK,oBAAoB,CAAA;IACpF,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAA;IAChB,CAAC;AACL,CAAC"}
@@ -1,85 +1,100 @@
1
1
  import { spawnSync } from 'node:child_process';
2
- import { existsSync } from 'node:fs';
3
- import { dirname, join, relative } from 'node:path';
2
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
4
  import { confirm, isCancel, log, spinner } from '@clack/prompts';
5
5
  import pc from 'picocolors';
6
- const APP_REPO_URL = 'git@github.com:tinycld/tinycld.git';
7
- const APP_DIR_NAME = 'tinycld';
6
+ import { bootstrapTooling } from "./bootstrap-tooling.js";
7
+ import { looksLikeWorkspaceRoot } from "./layout.js";
8
8
  /**
9
- * Returns true if the user chose to link (even if a subprocess failed —
10
- * the error is already logged, and we don't want to follow up with
11
- * "here are the manual steps" when the user already expressed intent).
12
- * Returns false only if linking was declined or skipped.
9
+ * Add `slug` to `<workspaceDir>/package.json` `workspaces[]` if it isn't already
10
+ * there. Idempotent, and a no-op when there's no package.json yet.
11
+ */
12
+ export function ensureMember(workspaceDir, slug) {
13
+ const pkgPath = join(workspaceDir, 'package.json');
14
+ if (!existsSync(pkgPath))
15
+ return;
16
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
17
+ pkg.workspaces = Array.isArray(pkg.workspaces) ? pkg.workspaces : [];
18
+ if (!pkg.workspaces.includes(slug)) {
19
+ pkg.workspaces.push(slug);
20
+ writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 4)}\n`);
21
+ }
22
+ }
23
+ /**
24
+ * Offer to link the freshly-scaffolded package into the TinyCld workspace.
25
+ *
26
+ * "Linking" in the workspace layout means: make the package a workspace member
27
+ * (its dir name appears in the root `package.json` `workspaces[]`) and run
28
+ * `npm install` at the workspace root — npm creates the `node_modules/@tinycld/*`
29
+ * symlink and the root `postinstall` runs the generator.
30
+ *
31
+ * Two shapes, distinguished by whether `workspaceDir` is already a workspace root:
32
+ * - attach: `workspaceDir` already holds the workspace meta-repo (its
33
+ * package.json name is `@tinycld/workspace`). No assembly — just ensure the
34
+ * member and install. The existing root package.json is left untouched.
35
+ * - bootstrap: `workspaceDir` is a fresh wrapper that only contains the
36
+ * scaffolded `<slug>/` so far. Assemble the workspace *around* it — write the
37
+ * workspace manifest and clone app + core via `bootstrapTooling` — then
38
+ * ensure the new member and install. The `postinstall` (`cd app && …`) only
39
+ * succeeds once `app/` exists, which is why we assemble before installing.
13
40
  *
14
- * Linking happens against the tinycld **app shell** (sibling repo
15
- * `tinycld/tinycld`), which owns `packages:link` and bundles `@tinycld/core`
16
- * at `packages/@tinycld/core/`. This package's tsconfig
17
- * (`"@tinycld/core/*": ["../tinycld/packages/@tinycld/core/*"]`) and its Go
18
- * server's `replace tinycld.org/core => ../../tinycld/packages/@tinycld/core/server`
19
- * directive both resolve into the bundled core inside the app shell.
41
+ * Returns true if the user chose to link (even if a subprocess failed — the
42
+ * error is already logged, and we don't want to follow up with manual steps
43
+ * when the user already expressed intent). Returns false only when linking was
44
+ * declined or skipped.
20
45
  */
21
- export async function offerLinkPackage({ packageName, targetDir, mode }) {
46
+ export async function offerLinkPackage({ slug, workspaceDir, mode, assemble = realAssemble, install = realInstall, }) {
22
47
  if (mode === 'skip')
23
48
  return false;
24
- const parentDir = dirname(targetDir);
25
- const appDir = join(parentDir, APP_DIR_NAME);
26
- const appExists = existsSync(appDir);
49
+ // A wrapper that isn't yet a workspace root needs app + core assembled in.
50
+ const needsClone = !looksLikeWorkspaceRoot(workspaceDir);
27
51
  if (mode === 'prompt') {
28
- const prompt = appExists
29
- ? `Link ${pc.bold(packageName)} into ${pc.bold(APP_DIR_NAME)} now?`
30
- : `Clone ${pc.bold(APP_DIR_NAME)} (shallow) and link ${pc.bold(packageName)} into it now?`;
31
- const answer = await confirm({ message: prompt, initialValue: true });
52
+ const message = needsClone
53
+ ? `Clone the tinycld workspace (app + core) and link ${pc.bold(slug)} now?`
54
+ : `Link ${pc.bold(slug)} into the workspace now?`;
55
+ const answer = await confirm({ message, initialValue: true });
32
56
  if (isCancel(answer) || answer !== true)
33
57
  return false;
34
58
  }
35
- if (!appExists) {
36
- if (!cloneRepo(APP_REPO_URL, appDir))
59
+ if (needsClone) {
60
+ const s = spinner();
61
+ s.start('Assembling the tinycld workspace (app + core)');
62
+ try {
63
+ assemble(workspaceDir);
64
+ }
65
+ catch (err) {
66
+ s.stop(pc.red('Workspace assembly failed'), 1);
67
+ log.error(err instanceof Error ? err.message : String(err));
37
68
  return true;
69
+ }
70
+ s.stop('Assembled the tinycld workspace');
38
71
  }
39
- else {
40
- log.info(`Using existing ${APP_DIR_NAME} at ${appDir}`);
41
- }
42
- const install = spinner();
43
- install.start(`Installing ${APP_DIR_NAME} dependencies (npm install)`);
44
- const inst = spawnSync('npm', ['install'], { cwd: appDir, stdio: 'pipe', encoding: 'utf8' });
45
- if (inst.status !== 0) {
46
- install.stop(pc.red('npm install failed'), 1);
47
- log.error(inst.stderr.trim() || 'npm install exited non-zero');
48
- return true;
49
- }
50
- install.stop(`Installed ${APP_DIR_NAME} dependencies`);
51
- // packages:link in tinycld takes a sibling-directory locator and reads
52
- // the package name from the sibling's package.json. Pass a path relative
53
- // to the app shell so the symlink target stays portable.
54
- const link = spinner();
55
- link.start(`Linking ${packageName}`);
56
- const locator = relative(appDir, targetDir) || targetDir;
57
- const linkResult = spawnSync('npm', ['run', 'packages:link', locator], {
58
- cwd: appDir,
59
- stdio: 'pipe',
60
- encoding: 'utf8',
61
- });
62
- if (linkResult.status !== 0) {
63
- link.stop(pc.red('Link failed'), 1);
64
- log.error(linkResult.stderr.trim() || 'packages:link exited non-zero');
72
+ ensureMember(workspaceDir, slug);
73
+ const i = spinner();
74
+ i.start('Installing workspace (npm install)');
75
+ if (!install(workspaceDir)) {
76
+ i.stop(pc.red('npm install failed'), 1);
65
77
  return true;
66
78
  }
67
- link.stop(`Linked ${packageName} into ${APP_DIR_NAME}`);
79
+ i.stop('Installed workspace');
80
+ log.success(`Linked ${pc.bold(slug)} into the workspace`);
68
81
  return true;
69
82
  }
70
- function cloneRepo(url, dest) {
71
- const s = spinner();
72
- s.start(`Cloning ${url} into ${dest}`);
73
- const result = spawnSync('git', ['clone', '--depth', '1', url, dest], {
74
- stdio: 'pipe',
75
- encoding: 'utf8',
76
- });
77
- if (result.status !== 0) {
78
- s.stop(pc.red('Clone failed'), 1);
79
- log.error(result.stderr.trim() || 'git clone exited non-zero');
83
+ /**
84
+ * Assemble the workspace skeleton at `dir`: write the workspace manifest and
85
+ * clone app + core (honoring `TINYCLD_REPO_BASE` for keyless/HTTPS envs).
86
+ * `bootstrapTooling` is synchronous and throws on failure (unknown member, etc.);
87
+ * `offerLinkPackage` wraps the call so the error surfaces in the spinner.
88
+ */
89
+ function realAssemble(dir) {
90
+ bootstrapTooling({ root: dir, repoBase: process.env.TINYCLD_REPO_BASE });
91
+ }
92
+ function realInstall(cwd) {
93
+ const r = spawnSync('npm', ['install'], { cwd, stdio: 'pipe', encoding: 'utf8' });
94
+ if (r.status !== 0) {
95
+ log.error(r.stderr?.trim() || 'npm install exited non-zero');
80
96
  return false;
81
97
  }
82
- s.stop(`Cloned ${dest}`);
83
98
  return true;
84
99
  }
85
100
  //# sourceMappingURL=link-package.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"link-package.js","sourceRoot":"","sources":["../src/link-package.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"link-package.js","sourceRoot":"","sources":["../src/link-package.ts"],"names":[],"mappings":"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"}
package/dist/prompts.js CHANGED
@@ -165,9 +165,9 @@ async function resolveTarget(fromArgv, slug, skipPrompts) {
165
165
  return abs;
166
166
  }
167
167
  // No --target: pick a sensible default based on the cwd's existing layout.
168
- // If cwd already has a tinycld/ app shell child, attach the new package
169
- // alongside it as `<cwd>/<slug>`. Otherwise bootstrap a wrapper workspace
170
- // under `<cwd>/tinycld-<slug>/` and place the package inside it.
168
+ // If cwd is itself a workspace root, attach the new package as a direct
169
+ // child `<cwd>/<slug>`. Otherwise bootstrap a wrapper workspace under
170
+ // `<cwd>/tinycld-<slug>/` and place the package inside it.
171
171
  const layout = detectLayout(slug);
172
172
  const defaultAbs = layout.targetDir;
173
173
  const defaultDisplay = `./${relative(process.cwd(), defaultAbs) || slug}`;
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinycld/bootstrap",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Scaffolder for @tinycld feature packages",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -17,7 +17,13 @@
17
17
  "./components/*": "./tinycld/{{PKG_SLUG}}/components/*.tsx"
18
18
  },
19
19
  "scripts": {
20
- "typecheck": "tsc --noEmit --skipLibCheck"
20
+ "typecheck": "tinycld-pkg typecheck",
21
+ "test": "tinycld-pkg test",
22
+ "test:e2e": "tinycld-pkg test:e2e",
23
+ "check": "tinycld-pkg check"
24
+ },
25
+ "devDependencies": {
26
+ "@tinycld/package-scripts": "*"
21
27
  },
22
28
  "peerDependencies": {
23
29
  "react": ">=19",
@@ -0,0 +1,20 @@
1
+ import path from 'node:path'
2
+ import { defineConfig } from '@playwright/test'
3
+ import appConfig from '../app/playwright.config'
4
+
5
+ // Package-scoped Playwright: inherit the app shell's webServer + browser config,
6
+ // then point testDir at THIS package's tests/e2e through the app shell's
7
+ // node_modules symlink. Routing via node_modules (not this repo's real path)
8
+ // keeps node resolution walking up into the app shell's install, so
9
+ // @playwright/test and other deps resolve there — not from a (nonexistent)
10
+ // local node_modules.
11
+ // The @tinycld/{{PKG_SLUG}} symlink lives in the workspace-root node_modules (deps
12
+ // hoist there in this layout). Routing testDir through it keeps node resolution
13
+ // walking up into the install where @playwright/test lives.
14
+ const WS_ROOT = path.resolve(import.meta.dirname, '..')
15
+ const TEST_DIR = path.join(WS_ROOT, 'node_modules', '@tinycld', '{{PKG_SLUG}}', 'tests', 'e2e')
16
+
17
+ export default defineConfig({
18
+ ...appConfig,
19
+ testDir: TEST_DIR,
20
+ })
@@ -3,8 +3,8 @@ module {{GO_MODULE}}
3
3
  go 1.25.0
4
4
 
5
5
  require (
6
- github.com/pocketbase/pocketbase v0.36.8
6
+ github.com/pocketbase/pocketbase v0.37.5
7
7
  tinycld.org/core v0.0.0
8
8
  )
9
9
 
10
- replace tinycld.org/core => ../../tinycld/packages/@tinycld/core/server
10
+ replace tinycld.org/core => ../../core/server
@@ -13,7 +13,12 @@
13
13
  "./hooks/*": "./tinycld/{{PKG_SLUG}}/hooks/*.ts"
14
14
  },
15
15
  "scripts": {
16
- "typecheck": "tsc --noEmit --skipLibCheck"
16
+ "typecheck": "tinycld-pkg typecheck",
17
+ "test": "tinycld-pkg test",
18
+ "check": "tinycld-pkg check"
19
+ },
20
+ "devDependencies": {
21
+ "@tinycld/package-scripts": "*"
17
22
  },
18
23
  "peerDependencies": {
19
24
  "react": ">=19",
@@ -7,53 +7,77 @@ on:
7
7
  branches: [main]
8
8
 
9
9
  env:
10
- APP_REPO: tinycld/tinycld
11
- APP_REF: main
10
+ PACKAGE: {{PKG_SLUG}}
11
+ TEST_USER_LOGIN: user@tinycld.org
12
+ TEST_USER_PW: TestUser1234!
13
+ ADMIN_USER_LOGIN: admin@tinycld.org
14
+ ADMIN_USER_PW: AdminPass1234!
12
15
 
13
16
  jobs:
14
- checks:
15
- name: Lint, typecheck, unit tests
17
+ check:
18
+ name: Typecheck & Unit
16
19
  runs-on: ubuntu-latest
17
20
  steps:
21
+ # 1. The workspace meta-repo becomes the job root.
18
22
  - uses: actions/checkout@v5
19
23
  with:
20
- path: {{PKG_SLUG}}
24
+ repository: tinycld/workspace
25
+ ref: main
26
+ path: ws
27
+ # 2. This PR's code, checked out into the member slot.
21
28
  - uses: actions/checkout@v5
22
29
  with:
23
- repository: ${{ env.APP_REPO }}
24
- ref: ${{ env.APP_REF }}
25
- path: tinycld
30
+ path: ws/${{ env.PACKAGE }}
26
31
  - uses: actions/setup-node@v5
27
32
  with:
28
- node-version-file: tinycld/.node-version
33
+ node-version-file: ws/.node-version
29
34
  cache: npm
30
- cache-dependency-path: tinycld/package-lock.json
31
-
32
- # The app shell bundles @tinycld/core at packages/@tinycld/core/. This
33
- # package's tsconfig path "@tinycld/core/*":
34
- # ["../tinycld/packages/@tinycld/core/*"] and its server go.mod replace
35
- # directive both point directly there.
36
- - name: Install app shell deps
37
- working-directory: tinycld
38
- run: npm ci
39
-
40
- - name: Link {{PKG_SLUG}} into tinycld app shell
41
- working-directory: tinycld
42
- run: npm run packages:link ../{{PKG_SLUG}}
43
-
44
- - name: Lint (biome lives in tinycld and lints linked {{PKG_SLUG}} via app rules)
45
- working-directory: tinycld
46
- run: npm run lint
47
-
48
- # Typecheck runs from inside tinycld so module resolution sees the
49
- # full app-shell tree (uniwind augments, expo types, etc) — running
50
- # tsc standalone in the package directory misses those.
51
- - name: Typecheck (full app shell, package included via link)
52
- working-directory: tinycld
53
- env:
54
- NODE_OPTIONS: --preserve-symlinks
55
- run: npm run typecheck
35
+ cache-dependency-path: ws/package-lock.json
36
+ - uses: actions/setup-go@v6
37
+ with:
38
+ go-version-file: ws/.go-version
39
+ # 3. Clone app + core (the PR's PACKAGE is already checked out into its
40
+ # slot; bootstrap --tooling skips dirs that already exist). A sibling
41
+ # only needs app + core + itself to typecheck + unit-test.
42
+ - name: Assemble workspace (app + core)
43
+ working-directory: ws
44
+ run: TINYCLD_REPO_BASE=https://github.com/tinycld npx @tinycld/bootstrap@latest --tooling
45
+ - name: Install (workspace root)
46
+ working-directory: ws
47
+ run: npm install
48
+ - name: Typecheck + unit
49
+ working-directory: ws/${{ env.PACKAGE }}
50
+ run: npx tinycld-pkg check
56
51
 
57
- - name: Run unit tests
58
- working-directory: {{PKG_SLUG}}
59
- run: npx vitest run
52
+ e2e:
53
+ name: E2E
54
+ runs-on: ubuntu-latest
55
+ steps:
56
+ - uses: actions/checkout@v5
57
+ with:
58
+ repository: tinycld/workspace
59
+ ref: main
60
+ path: ws
61
+ - uses: actions/checkout@v5
62
+ with:
63
+ path: ws/${{ env.PACKAGE }}
64
+ - uses: actions/setup-node@v5
65
+ with:
66
+ node-version-file: ws/.node-version
67
+ cache: npm
68
+ cache-dependency-path: ws/package-lock.json
69
+ - uses: actions/setup-go@v6
70
+ with:
71
+ go-version-file: ws/.go-version
72
+ - name: Assemble workspace (app + core)
73
+ working-directory: ws
74
+ run: TINYCLD_REPO_BASE=https://github.com/tinycld npx @tinycld/bootstrap@latest --tooling
75
+ - name: Install (workspace root)
76
+ working-directory: ws
77
+ run: npm install
78
+ - name: Install Playwright browsers
79
+ working-directory: ws/app
80
+ run: npx playwright install --with-deps chromium
81
+ - name: E2E
82
+ working-directory: ws/${{ env.PACKAGE }}
83
+ run: npx tinycld-pkg test:e2e
@@ -2,53 +2,64 @@
2
2
 
3
3
  {{PKG_DESCRIPTION}}
4
4
 
5
- Feature package for the [tinycld](https://github.com/tinycld/tinycld) ecosystem. Lives as a standalone git repo alongside the [`tinycld`](https://github.com/tinycld/tinycld) app shell and other sibling packages (`contacts`, `mail`, `calendar`, `drive`, `google-takeout-import`). The app shell bundles `@tinycld/core` inside it — there is no separate core repo to clone.
5
+ A feature package for the [tinycld](https://tinycld.org/) ecosystem. It lives in
6
+ its own git repo and is developed as a **workspace member** alongside the app
7
+ shell (`app`), `@tinycld/core` (its own standalone repo, cloned as a sibling —
8
+ not bundled), and the other feature packages.
6
9
 
7
10
  ## Development
8
11
 
12
+ The package is one member of a tinycld workspace. To work on it you need a
13
+ workspace root containing at least `app`, `core`, and this package as siblings,
14
+ linked by a single `npm install` at the root.
15
+
9
16
  ```sh
10
- # Clone the app shell and this package as siblings
11
- cd ~/code/tinycld
12
- git clone git@github.com:tinycld/tinycld.git
17
+ # In a fresh workspace directory, clone this package into a member slot…
13
18
  git clone git@github.com:tinycld/{{PKG_SLUG}}.git
14
19
 
15
- # Install deps in the app shell
16
- cd tinycld
17
- npm install
20
+ # …then pull in the rest of the workspace tooling (app + core + the root
21
+ # package.json / lockfile). bootstrap --tooling skips dirs that already exist.
22
+ npx @tinycld/bootstrap@latest --tooling
18
23
 
19
- # Link this package into the app shell
20
- npm run packages:link ../{{PKG_SLUG}}
24
+ # Link every member with one install at the WORKSPACE ROOT (never inside a
25
+ # member — siblings have no node_modules of their own; deps hoist to the root).
26
+ npm install
21
27
 
22
- # Run the full stack
23
- npm run start
28
+ # Run the full stack (Expo + PocketBase, single-port dev proxy) from the app.
29
+ cd app
30
+ npm run dev
24
31
  ```
25
32
 
26
- ## Standalone checks
33
+ ## Checks
27
34
 
28
- Lint and typecheck both run from the app shell — biome and TypeScript live
29
- there, and the app shell's tsconfig pulls in `expo`'s base config, `uniwind`
30
- type augments, and the live `~/types/pbSchema` generated from PocketBase,
31
- none of which a standalone invocation in this package can see. Biome's
32
- config lives in `tinycld/biome.json` and applies to every linked package
33
- (there is no `biome.json` in this repo).
35
+ All checks run **scoped to this member** through `tinycld-pkg`, which reuses the
36
+ app shell's biome config, tsconfig base, and vitest/playwright configs (so
37
+ `@tinycld/core/*`, uniwind augments, and PocketBase types all resolve):
34
38
 
35
39
  ```sh
36
- cd ../tinycld
37
- npm run packages:link ../{{PKG_SLUG}} # only needed once per checkout
38
- npm run lint # scans this package via the app's biome rules
39
- npm run typecheck # full app-shell tsc
40
+ cd {{PKG_SLUG}}
41
+ npx tinycld-pkg check # biome + typecheck
42
+ npx tinycld-pkg test # vitest unit tests
43
+ npx tinycld-pkg test:e2e # playwright e2e specs (full preset only — packages with screens)
40
44
  ```
41
45
 
46
+ There is no `biome.json` in this repo — biome lives only in the app shell and
47
+ `tinycld-pkg` points it at this member's source.
48
+
42
49
  ## CI
43
50
 
44
- `.github/workflows/ci.yml` runs lint, typecheck, and vitest on every push to
45
- `main` and every PR. It clones `tinycld/tinycld@main` into a sibling
46
- directory, installs the app shell's deps, links this package in, and runs
47
- the checks — exactly what a developer does locally.
51
+ `.github/workflows/ci.yml` runs typecheck, unit tests, and e2e on every push to
52
+ `main` and every PR. It checks out `tinycld/workspace` as the job root, drops
53
+ this PR's code into its member slot, assembles `app` + `core` via
54
+ `@tinycld/bootstrap --tooling`, installs at the workspace root, and runs
55
+ `tinycld-pkg check` / `tinycld-pkg test:e2e` — exactly what a developer runs
56
+ locally.
48
57
 
49
58
  ## Package anatomy
50
59
 
51
60
  - `manifest.ts` — the single source of truth for this package's capabilities
52
- - `package.json` — name, exports map, peer deps
53
- - `tsconfig.json` — typecheck config (lint config lives in the app shell's `biome.json`)
54
- - `tests/` — vitest unit tests
61
+ - `package.json` — name, exports map, `tinycld-pkg` scripts, peer deps
62
+ - `tsconfig.json` — extends the app shell's package tsconfig base
63
+ - `vitest.config.ts` (and `playwright.config.ts` — full preset only) — thin configs spreading the app's
64
+ - `tinycld/{{PKG_SLUG}}/` — the package's TypeScript surface (screens, collections, …)
65
+ - `tests/` — vitest unit tests (and Playwright e2e specs — full preset only)
@@ -1,22 +1,13 @@
1
1
  {
2
- "extends": "../tinycld/tsconfig.json",
2
+ "extends": "../app/tsconfig.package-base.json",
3
3
  "compilerOptions": {
4
4
  "baseUrl": ".",
5
- "rootDir": "..",
6
5
  "paths": {
7
6
  "~/tinycld/{{PKG_SLUG}}/*": ["./tinycld/{{PKG_SLUG}}/*"],
8
- "@tinycld/app-generated/*": ["../tinycld/lib/generated/*"],
9
- "@tinycld/core/*": ["../tinycld/packages/@tinycld/core/*"],
10
- "~/*": ["../tinycld/packages/@tinycld/core/*"]
11
- },
12
- "noEmit": true,
13
- "preserveSymlinks": false
7
+ "@tinycld/core/*": ["../core/*"],
8
+ "@tinycld/app-generated/*": ["../app/lib/generated/*"]
9
+ }
14
10
  },
15
- "include": [
16
- "**/*.ts",
17
- "**/*.tsx",
18
- "../tinycld/uniwind-types.d.ts",
19
- "../tinycld/expo-env.d.ts"
20
- ],
11
+ "include": ["tinycld/**/*.ts", "tinycld/**/*.tsx", "../app/uniwind-types.d.ts"],
21
12
  "exclude": ["node_modules", "server", "pb-migrations", "tests/**/*.spec.ts"]
22
13
  }
@@ -0,0 +1,16 @@
1
+ import path from 'node:path'
2
+ import { mergeConfig } from 'vitest/config'
3
+ import appConfig from '../app/vitest.config'
4
+
5
+ // Package-scoped vitest: inherit the app shell's canonical aliases (so
6
+ // @tinycld/core/* etc. resolve identically), then add this package's own
7
+ // `~/*` source alias and scope the run to this package's tests/.
8
+ export default mergeConfig(appConfig, {
9
+ resolve: {
10
+ alias: [{ find: /^~\/(.+)$/, replacement: path.resolve(__dirname, '$1') }],
11
+ },
12
+ test: {
13
+ root: __dirname,
14
+ include: ['tests/**/*.test.{ts,tsx}'],
15
+ },
16
+ })