@_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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localize.js","sourceRoot":"","sources":["../../../src/localize/localize.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `localize` -- turn an npm-installed dependency into an editable git checkout.\n *\n * The loop, in five steps, none of which involve npm learning anything:\n *\n * 1. npm name -> registry `repository` (see resolve.ts)\n * 2. `git clone` into `<dir>/<name>`\n * 3. **`npm install` INSIDE the checkout**, then prune it (`ensure`)\n * 4. `fs.symlink` node_modules/<name> -> the checkout\n * 5. record it in a gitignored manifest\n *\n * `adopt` (adopt.ts) enters at step 3 with a checkout that is already there,\n * and shares everything from there on: `forEachName` and `installLinkAndRecord`\n * below.\n *\n * Step 3 is the one that is easy to \"simplify\" and must not be. Installing\n * from the parent instead -- `npm install <path> --no-save` -- hard-failed an\n * app's boot on a missing peer dependency, because module resolution happens\n * from the symlink's REAL path, whose ancestors have no `node_modules`. The\n * checkout needs its own installed tree. `tests/unit/localize/real-localize.test.ts` runs a\n * real clone and a real install and asserts the dependency landed inside the\n * checkout, so a reimplementation that moves the install back out fails there.\n *\n * A clone, not a copy: a published tarball has no `src/`, so copying the\n * installed package cannot give you something to edit.\n *\n * What localize NEVER does: run an install at the consumer root, or edit\n * `package.json`, `package-lock.json`, `.gitignore`, `workspaces` or any\n * bundler config. It asserts it did not before exiting 0.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n EXIT_INSTALL_FAILED,\n EXIT_NOT_FOUND,\n EXIT_MANIFEST_DIRTY,\n EXIT_REFUSED,\n EXIT_WARNED,\n LocalizeError,\n} from './errors.js';\nimport {\n DEFAULT_DIR,\n SCHEMA_VERSION,\n readManifest,\n writeManifest,\n} from './manifest.js';\nimport type {ManifestEntry} from './manifest.js';\nimport type {Deps} from './run.js';\nimport {checkoutNameFor, resolvePackage} from './resolve.js';\nimport {pruneProvided, shouldPrune} from './prune.js';\nimport {ensure} from './ensure.js';\nimport type {PruneOptions} from './prune.js';\nimport {\n diffManifests,\n isGitCheckout,\n isInside,\n isSymlink,\n readJson,\n snapshotManifests,\n writeLink,\n} from './fsops.js';\n\n/**\n * @param {string[]} names full npm package names\n * @param {object} opts `{force, dir, repo, subdir, build, prune}` -- `prune`\n * defaults to true; see prune.ts\n * @param {object} deps `{appRoot, run, log, warn, error}`\n * @returns {number} the process exit code: the HIGHEST of the per-name codes,\n * since each name is atomic and a failure on name 2 does not undo name 1.\n */\nexport interface LocalizeOptions extends PruneOptions {\n force?: boolean;\n /** Where checkouts live, relative to the app root (default `packages-local`). */\n dir?: string;\n repo?: string;\n subdir?: string;\n /** Run in the checkout after installing; absent or empty runs nothing. */\n build?: string;\n}\n\n/** What one name's work returns to the shared loop. */\nexport interface OneResult {\n code: number;\n entry?: {name: string; value: ManifestEntry};\n}\n\nexport type OneName = (\n name: string,\n dir: string,\n recorded: ManifestEntry | undefined,\n opts: LocalizeOptions,\n deps: Deps,\n) => OneResult;\n\nexport function localize(\n names: string[],\n opts: LocalizeOptions,\n deps: Deps,\n): number {\n return forEachName(names, opts, deps, localizeOne);\n}\n\n/**\n * The loop `localize` and `adopt` share: read the manifest once, run `one` per\n * name, write the manifest after each, then assert the links and the\n * consumer's untouched manifests.\n *\n * @param {(name: string, dir: string, recorded: object|undefined, opts: object, deps: object)\n * => {code: number, entry?: {name: string, value: object}}} one\n */\nexport function forEachName(\n names: string[],\n opts: LocalizeOptions,\n deps: Deps,\n one: OneName,\n): number {\n // Taken BEFORE anything runs: the post-condition is about what THIS run\n // changed, not about what the tree looked like at HEAD.\n const before = snapshotManifests(deps.appRoot);\n\n let manifest;\n try {\n manifest = readManifest(deps.appRoot, deps);\n } catch (e) {\n return reportError(e, deps);\n }\n\n const dir = opts.dir ?? manifest.dir ?? DEFAULT_DIR;\n const entries = {...manifest.entries};\n let code = 0;\n\n for (const name of names) {\n try {\n const result = one(name, dir, entries[name], opts, deps);\n if (result.entry) entries[result.entry.name] = result.entry.value;\n code = Math.max(code, result.code);\n // Written after EACH name, so an interruption keeps what already worked.\n writeManifest(deps.appRoot, {\n version: SCHEMA_VERSION,\n dir,\n packages: entries,\n });\n } catch (e) {\n code = Math.max(code, reportError(e, deps));\n }\n }\n\n // Over EVERY localized checkout, not just the ones named: localizing `B`\n // is what makes `A`'s registry copy of `B` redundant.\n if (shouldPrune(opts)) {\n try {\n pruneProvided(entries, opts, deps);\n } catch (e) {\n deps.warn(\n `[localize] pruning failed, the checkouts' node_modules are as npm left them: ${e.message}`,\n );\n code = Math.max(code, EXIT_WARNED);\n }\n }\n\n code = Math.max(code, assertLinked(entries, deps));\n code = Math.max(code, assertManifestsUntouched(before, deps));\n return code;\n}\n\nfunction localizeOne(\n name: string,\n dir: string,\n recorded: ManifestEntry | undefined,\n opts: LocalizeOptions,\n deps: Deps,\n): OneResult {\n // An override recorded by an earlier run is reused, so `--repo` is a\n // one-time cost rather than something to remember on every invocation.\n const override = opts.repo\n ? {repo: opts.repo, subdir: opts.subdir}\n : recorded?.repo && !looksLikeOrgSlug(recorded.repo)\n ? {repo: recorded.repo, subdir: recorded.subdir}\n : undefined;\n\n const resolved = resolveOrSuggestAdopt(name, dir, override, deps);\n let code = 0;\n\n const relClone = path.join(dir, resolved.checkoutName);\n const clone = path.join(deps.appRoot, relClone);\n // When the repository holds more than this package, the CHECKOUT is the\n // clone but the PACKAGE is a directory inside it: that is where the install\n // runs and that is what the symlink points at.\n const relPkg = resolved.subdir\n ? path.join(relClone, resolved.subdir)\n : relClone;\n const pkgDir = path.join(deps.appRoot, relPkg);\n\n guardForeignLink(resolved.npmName, dir, opts, deps);\n\n if (isGitCheckout(clone)) {\n code = Math.max(code, refresh(relClone, clone, deps));\n if (code === EXIT_WARNED) return {code}; // a non-fast-forward is reported, never forced\n } else {\n fs.mkdirSync(path.dirname(clone), {recursive: true});\n deps.log(`[localize] cloning ${resolved.repo} -> ${relClone}`);\n const r = deps.run('git', ['clone', resolved.repo, clone]);\n if (r.status !== 0) {\n throw new LocalizeError(\n `git clone ${resolved.repo} failed:\\n${(r.stderr || r.stdout).trim()}`,\n EXIT_REFUSED,\n );\n }\n }\n\n if (!fs.existsSync(path.join(pkgDir, 'package.json'))) {\n throw new LocalizeError(\n `${relPkg} has no package.json, so it is not the package \"${name}\".\\n` +\n (resolved.subdir\n ? `The registry says \"${name}\" lives in \"${resolved.subdir}\" of ${resolved.repo}, and it does not.`\n : `${resolved.repo} looks like a monorepo root. Say where the package lives:\\n` +\n ` linked localize ${name} --repo ${resolved.repo} --subdir <path-inside-the-repo>`),\n EXIT_REFUSED,\n );\n }\n\n // The checkout's own package.json is authoritative about the name: a\n // mismatch means the symlink would be written under a name nothing imports.\n const declared = readJson(path.join(pkgDir, 'package.json'))?.name;\n if (declared && declared !== resolved.npmName) {\n throw new LocalizeError(\n `${relPkg} declares itself as \"${declared}\", not \"${name}\".\\n` +\n (resolved.subdir\n ? `The registry's repository.directory for \"${name}\" points at the wrong package.`\n : `${resolved.repo} is probably a monorepo. Point at the right directory:\\n` +\n ` linked localize ${name} --repo ${resolved.repo} --subdir <path-inside-the-repo>`),\n EXIT_REFUSED,\n );\n }\n\n return installLinkAndRecord(\n {\n npmName: resolved.npmName,\n clone,\n relPkg,\n pkgDir,\n repo: resolved.repo,\n subdir: resolved.subdir,\n },\n opts,\n deps,\n code,\n );\n}\n\n/**\n * Everything after the checkout exists, shared by `localize` and `adopt`:\n * install inside it, run the configured build, link it, and describe the\n * manifest entry. Nothing here knows how the checkout got there.\n *\n * `repo` may be absent -- an adopted checkout with no remote is recorded\n * without one.\n */\nexport function installLinkAndRecord(\n {\n npmName,\n clone,\n relPkg,\n pkgDir,\n repo,\n subdir,\n }: {\n npmName: string;\n clone: string;\n relPkg: string;\n pkgDir: string;\n repo?: string;\n subdir?: string;\n },\n opts: LocalizeOptions,\n deps: Deps,\n code = 0,\n): {code: number; entry: {name: string; value: ManifestEntry}} {\n // THE constraint. Read the module header before changing this. `ensure`\n // installs inside the checkout and prunes it as one step (ensure.ts).\n try {\n code = Math.max(code, ensure({path: relPkg, subdir}, deps, opts));\n } catch (e) {\n if (e instanceof LocalizeError && e.code === EXIT_INSTALL_FAILED)\n e.message += `\\nThe checkout is left on disk. Nothing was linked and nothing was recorded.`;\n throw e;\n }\n\n // The build is the one thing localize does not know how to do, so it is\n // configuration rather than behaviour. A failure is a WARNING: a package\n // whose build is broken is exactly what you are about to fix, and refusing\n // to link it would be perverse.\n if (runBuild(relPkg, pkgDir, opts, deps) === 'failed')\n code = Math.max(code, EXIT_WARNED);\n\n writeLink(deps.appRoot, npmName, pkgDir);\n const branch = currentBranch(clone, deps);\n deps.log(`[localize] linked ${npmName} -> ${relPkg} (branch ${branch})`);\n\n const range = declaredRange(npmName, deps);\n return {\n code,\n entry: {\n name: npmName,\n value: {\n ...(repo ? {repo} : {}),\n path: relPkg,\n branch,\n ...(subdir ? {subdir} : {}),\n ...(range ? {range} : {}),\n // `--no-prune` is remembered, so the run-time check and `--relink` honour it too.\n ...(shouldPrune(opts) ? {} : {prune: false as const}),\n },\n },\n };\n}\n\n/**\n * A registry lookup that fails while a git checkout already sits where the\n * clone would go is almost always a package that was never published -- one\n * made locally. Say how to link it as it is rather than leave the developer\n * guessing at a `--repo`.\n */\nfunction resolveOrSuggestAdopt(name, dir, override, deps) {\n try {\n return resolvePackage(name, deps, override);\n } catch (e) {\n const relClone = path.join(dir, checkoutNameFor(name));\n if (\n e instanceof LocalizeError &&\n e.code === EXIT_NOT_FOUND &&\n isGitCheckout(path.join(deps.appRoot, relClone))\n ) {\n e.message +=\n `\\n${relClone} is already a git checkout. To link it as it is, with no registry lookup:\\n` +\n ` linked localize ${name} --adopt`;\n }\n throw e;\n }\n}\n\n/** Older manifests recorded `owner/repo`; those are re-resolved rather than cloned blind. */\nfunction looksLikeOrgSlug(repo) {\n return /^[\\w.-]+\\/[\\w.-]+$/.test(repo);\n}\n\n/**\n * Reuse an existing clone. A dirty tree is reused WITHOUT pulling and said so;\n * a clean one is fast-forwarded; a non-fast-forward is reported and skipped\n * rather than forced, because the developer's commits are the entire point.\n */\nfunction refresh(relPath, clone, deps) {\n const status = deps.run('git', ['status', '--porcelain'], {cwd: clone});\n const modified = status.stdout.split('\\n').filter((l) => l.trim()).length;\n if (modified > 0) {\n deps.log(\n `[localize] ${relPath}: ${modified} modified file${modified === 1 ? '' : 's'} — not pulling`,\n );\n return 0;\n }\n const pull = deps.run('git', ['pull', '--ff-only'], {cwd: clone});\n if (pull.status !== 0) {\n deps.warn(\n `[localize] ${relPath}: \\`git pull --ff-only\\` failed (not a fast-forward) — skipped, not ` +\n `forced. Reconcile it by hand:\\n${(pull.stderr || pull.stdout).trim()}`,\n );\n return EXIT_WARNED;\n }\n return 0;\n}\n\n/**\n * Run the configured build command, if there is one.\n *\n * localize has no opinion about how a checkout is built, and does not look for\n * a builder. `--build \"<cmd>\"`, or a `build` field in the manifest, or\n * `{build}` in the programmatic options. Absent -- the common case, and the\n * case for anything whose dev loop reads source directly -- nothing runs and\n * nothing is said.\n */\nfunction runBuild(relPath, pkgDir, opts, deps) {\n const cmd = opts.build;\n if (!cmd) return 'skipped';\n deps.log(`[localize] ${relPath}: ${cmd}`);\n const r = deps.run(cmd, [], {cwd: pkgDir, shell: true});\n if (r.status !== 0) {\n deps.warn(\n `[localize] ${relPath}: \\`${cmd}\\` failed. The package is linked and recorded anyway — ` +\n `a package whose build is broken is exactly what you are about to fix.\\n` +\n `${(r.stderr || r.stdout).trim()}`,\n );\n return 'failed';\n }\n return 'ok';\n}\n\n/** Refuse when `node_modules/<name>` is already a symlink pointing outside `<dir>`. */\nexport function guardForeignLink(\n npmName: string,\n dir: string,\n opts: {force?: boolean},\n deps: Deps,\n): void {\n const link = path.join(deps.appRoot, 'node_modules', npmName);\n if (!isSymlink(link)) return;\n let target;\n try {\n target = fs.realpathSync(link);\n } catch {\n return; // a dangling link is ours to replace\n }\n if (isInside(target, path.join(deps.appRoot, dir))) return;\n if (opts.force) {\n deps.warn(\n `[localize] --force: overwriting the existing link ${npmName} -> ${target}`,\n );\n return;\n }\n throw new LocalizeError(\n `node_modules/${npmName} is already a symlink to ${target}, which is outside ${dir}.\\n` +\n `Refusing to overwrite someone else's link. Pass --force to replace it.`,\n EXIT_REFUSED,\n );\n}\n\n/** Every recorded package is actually linked where the manifest says it is. */\nfunction assertLinked(entries: Record<string, ManifestEntry>, deps: Deps) {\n let code = 0;\n for (const [name, entry] of Object.entries(entries)) {\n const link = path.join(deps.appRoot, 'node_modules', name);\n const expected = path.join(deps.appRoot, entry.path);\n if (!isSymlink(link)) {\n deps.warn(\n `[localize] ${name} is recorded but node_modules/${name} is not a symlink.`,\n );\n code = Math.max(code, EXIT_WARNED);\n continue;\n }\n if (!fs.existsSync(expected)) continue; // \"checkout missing\" is a --list state, not a failure\n if (fs.realpathSync(link) !== fs.realpathSync(expected)) {\n deps.warn(\n `[localize] ${name} links to ${fs.realpathSync(link)} but the manifest records ${entry.path}.`,\n );\n code = Math.max(code, EXIT_WARNED);\n }\n }\n return code;\n}\n\n/**\n * The property the whole design rests on: this run changed neither manifest.\n *\n * Content hashes, not `git status`. `git status` compares against HEAD, so in\n * any tree with an uncommitted `package.json` it reports a modification the\n * command did not make -- an earlier tool shipped exactly that and reported\n * correct runs as failures.\n */\nexport function assertManifestsUntouched(\n before: Record<string, string | null>,\n deps: Deps,\n): number {\n const changed = diffManifests(before, snapshotManifests(deps.appRoot));\n if (!changed.length) return 0;\n deps.error(\n `[localize] the consumer's manifests changed while this command ran:\\n` +\n changed.map((c) => ` ${c}`).join('\\n') +\n `\\nThis is the exact failure localize exists to prevent. Revert those files; nothing in ` +\n `localize is supposed to touch them.`,\n );\n return EXIT_MANIFEST_DIRTY;\n}\n\nexport function reportError(e: unknown, deps: Pick<Deps, 'error'>): number {\n if (e instanceof LocalizeError) {\n deps.error(`[localize] ${e.message}`);\n return e.code;\n }\n throw e;\n}\n\n/**\n * The checked-out branch, or `HEAD` when detached. `symbolic-ref` first,\n * because it also names the branch of a repository with no commits yet --\n * `rev-parse --abbrev-ref` fails there, and `create-package` adopts a fresh\n * `git init` before its first commit.\n */\nexport function currentBranch(clone: string, deps: Deps): string {\n const sym = deps.run('git', ['symbolic-ref', '--short', '-q', 'HEAD'], {\n cwd: clone,\n });\n if (sym.status === 0 && sym.stdout.trim()) return sym.stdout.trim();\n const r = deps.run('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd: clone,\n });\n const b = r.stdout.trim();\n return r.status === 0 && b ? b : 'HEAD';\n}\n\nexport function declaredRange(\n name: string,\n deps: Pick<Deps, 'appRoot'>,\n): string | undefined {\n const pkg = readJson(path.join(deps.appRoot, 'package.json'));\n if (!pkg) return undefined;\n return (\n pkg.dependencies?.[name] ??\n pkg.devDependencies?.[name] ??\n pkg.optionalDependencies?.[name]\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"localize.js","sourceRoot":"","sources":["../../../src/localize/localize.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `localize` -- turn an npm-installed dependency into an editable git checkout.\n *\n * The loop, in five steps, none of which involve npm learning anything:\n *\n * 1. npm name -> registry `repository` (see resolve.ts)\n * 2. `git clone` into `<dir>/<name>`\n * 3. **`npm install` INSIDE the checkout**, then prune it (`ensure`)\n * 4. `fs.symlink` node_modules/<name> -> the checkout\n * 5. record it in a gitignored manifest\n *\n * `adopt` (adopt.ts) enters at step 3 with a checkout that is already there,\n * and shares everything from there on: `forEachName` and `installLinkAndRecord`\n * below.\n *\n * Step 3 is the one that is easy to \"simplify\" and must not be. Installing\n * from the parent instead -- `npm install <path> --no-save` -- hard-failed an\n * app's boot on a missing peer dependency, because module resolution happens\n * from the symlink's REAL path, whose ancestors have no `node_modules`. The\n * checkout needs its own installed tree. `tests/unit/localize/real-localize.test.ts` runs a\n * real clone and a real install and asserts the dependency landed inside the\n * checkout, so a reimplementation that moves the install back out fails there.\n *\n * A clone, not a copy: a published tarball has no `src/`, so copying the\n * installed package cannot give you something to edit.\n *\n * What localize NEVER does: run an install at the consumer root, or edit\n * `package-lock.json`, `.gitignore`, `workspaces`, dependencies or any\n * bundler config. It asserts the work did not touch `package.json` or\n * `package-lock.json` before exiting 0.\n *\n * The one deliberate edit, made after that assertion: when a run records a\n * package, the app's `postinstall` and `dependencies` scripts get\n * `linked localize --relink` if they lack it (`../utils/relinkHooks.ts`\n * explains why npm needs both). Without them the next npm command silently\n * undoes the link this run just made.\n */\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n EXIT_INSTALL_FAILED,\n EXIT_NOT_FOUND,\n EXIT_MANIFEST_DIRTY,\n EXIT_REFUSED,\n EXIT_WARNED,\n LocalizeError,\n} from './errors.js';\nimport {\n DEFAULT_DIR,\n SCHEMA_VERSION,\n readManifest,\n writeManifest,\n} from './manifest.js';\nimport type {ManifestEntry} from './manifest.js';\nimport type {Deps} from './run.js';\nimport {checkoutNameFor, resolvePackage} from './resolve.js';\nimport {pruneProvided, shouldPrune} from './prune.js';\nimport {ensure} from './ensure.js';\nimport type {PruneOptions} from './prune.js';\nimport {ensureRelinkHooksInFile, RELINK_COMMAND} from '../utils/relinkHooks.js';\nimport {\n diffManifests,\n isGitCheckout,\n isInside,\n isSymlink,\n readJson,\n snapshotManifests,\n writeLink,\n} from './fsops.js';\n\n/**\n * @param {string[]} names full npm package names\n * @param {object} opts `{force, dir, repo, subdir, build, prune}` -- `prune`\n * defaults to true; see prune.ts\n * @param {object} deps `{appRoot, run, log, warn, error}`\n * @returns {number} the process exit code: the HIGHEST of the per-name codes,\n * since each name is atomic and a failure on name 2 does not undo name 1.\n */\nexport interface LocalizeOptions extends PruneOptions {\n force?: boolean;\n /** Where checkouts live, relative to the app root (default `packages-local`). */\n dir?: string;\n repo?: string;\n subdir?: string;\n /** Run in the checkout after installing; absent or empty runs nothing. */\n build?: string;\n}\n\n/** What one name's work returns to the shared loop. */\nexport interface OneResult {\n code: number;\n entry?: {name: string; value: ManifestEntry};\n}\n\nexport type OneName = (\n name: string,\n dir: string,\n recorded: ManifestEntry | undefined,\n opts: LocalizeOptions,\n deps: Deps,\n) => OneResult;\n\nexport function localize(\n names: string[],\n opts: LocalizeOptions,\n deps: Deps,\n): number {\n return forEachName(names, opts, deps, localizeOne);\n}\n\n/**\n * The loop `localize` and `adopt` share: read the manifest once, run `one` per\n * name, write the manifest after each, then assert the links and the\n * consumer's untouched manifests.\n *\n * @param {(name: string, dir: string, recorded: object|undefined, opts: object, deps: object)\n * => {code: number, entry?: {name: string, value: object}}} one\n */\nexport function forEachName(\n names: string[],\n opts: LocalizeOptions,\n deps: Deps,\n one: OneName,\n): number {\n // Taken BEFORE anything runs: the post-condition is about what THIS run\n // changed, not about what the tree looked like at HEAD.\n const before = snapshotManifests(deps.appRoot);\n\n let manifest;\n try {\n manifest = readManifest(deps.appRoot, deps);\n } catch (e) {\n return reportError(e, deps);\n }\n\n const dir = opts.dir ?? manifest.dir ?? DEFAULT_DIR;\n const entries = {...manifest.entries};\n let code = 0;\n let recorded = false;\n\n for (const name of names) {\n try {\n const result = one(name, dir, entries[name], opts, deps);\n if (result.entry) {\n entries[result.entry.name] = result.entry.value;\n recorded = true;\n }\n code = Math.max(code, result.code);\n // Written after EACH name, so an interruption keeps what already worked.\n writeManifest(deps.appRoot, {\n version: SCHEMA_VERSION,\n dir,\n packages: entries,\n });\n } catch (e) {\n code = Math.max(code, reportError(e, deps));\n }\n }\n\n // Over EVERY localized checkout, not just the ones named: localizing `B`\n // is what makes `A`'s registry copy of `B` redundant.\n if (shouldPrune(opts)) {\n try {\n pruneProvided(entries, opts, deps);\n } catch (e) {\n deps.warn(\n `[localize] pruning failed, the checkouts' node_modules are as npm left them: ${e.message}`,\n );\n code = Math.max(code, EXIT_WARNED);\n }\n }\n\n code = Math.max(code, assertLinked(entries, deps));\n code = Math.max(code, assertManifestsUntouched(before, deps));\n // After the assertion, so it still covers everything the work itself did.\n if (recorded) ensureRelinkHooksIn(deps);\n return code;\n}\n\n/** Add the relink hooks to the app's package.json when it lacks them. See relinkHooks.ts. */\nfunction ensureRelinkHooksIn(deps: Deps): void {\n const added = ensureRelinkHooksInFile(\n path.join(deps.appRoot, 'package.json'),\n );\n if (!added.length) return;\n deps.log(\n `[localize] Added \\`${RELINK_COMMAND}\\` to the app's ${added.join(' and ')} ` +\n `script${added.length > 1 ? 's' : ''} so npm keeps the links`,\n );\n}\n\nfunction localizeOne(\n name: string,\n dir: string,\n recorded: ManifestEntry | undefined,\n opts: LocalizeOptions,\n deps: Deps,\n): OneResult {\n // An override recorded by an earlier run is reused, so `--repo` is a\n // one-time cost rather than something to remember on every invocation.\n const override = opts.repo\n ? {repo: opts.repo, subdir: opts.subdir}\n : recorded?.repo && !looksLikeOrgSlug(recorded.repo)\n ? {repo: recorded.repo, subdir: recorded.subdir}\n : undefined;\n\n const resolved = resolveOrSuggestAdopt(name, dir, override, deps);\n let code = 0;\n\n const relClone = path.join(dir, resolved.checkoutName);\n const clone = path.join(deps.appRoot, relClone);\n // When the repository holds more than this package, the CHECKOUT is the\n // clone but the PACKAGE is a directory inside it: that is where the install\n // runs and that is what the symlink points at.\n const relPkg = resolved.subdir\n ? path.join(relClone, resolved.subdir)\n : relClone;\n const pkgDir = path.join(deps.appRoot, relPkg);\n\n guardForeignLink(resolved.npmName, dir, opts, deps);\n\n if (isGitCheckout(clone)) {\n code = Math.max(code, refresh(relClone, clone, deps));\n if (code === EXIT_WARNED) return {code}; // a non-fast-forward is reported, never forced\n } else {\n fs.mkdirSync(path.dirname(clone), {recursive: true});\n deps.log(`[localize] cloning ${resolved.repo} -> ${relClone}`);\n const r = deps.run('git', ['clone', resolved.repo, clone]);\n if (r.status !== 0) {\n throw new LocalizeError(\n `git clone ${resolved.repo} failed:\\n${(r.stderr || r.stdout).trim()}`,\n EXIT_REFUSED,\n );\n }\n }\n\n if (!fs.existsSync(path.join(pkgDir, 'package.json'))) {\n throw new LocalizeError(\n `${relPkg} has no package.json, so it is not the package \"${name}\".\\n` +\n (resolved.subdir\n ? `The registry says \"${name}\" lives in \"${resolved.subdir}\" of ${resolved.repo}, and it does not.`\n : `${resolved.repo} looks like a monorepo root. Say where the package lives:\\n` +\n ` linked localize ${name} --repo ${resolved.repo} --subdir <path-inside-the-repo>`),\n EXIT_REFUSED,\n );\n }\n\n // The checkout's own package.json is authoritative about the name: a\n // mismatch means the symlink would be written under a name nothing imports.\n const declared = readJson(path.join(pkgDir, 'package.json'))?.name;\n if (declared && declared !== resolved.npmName) {\n throw new LocalizeError(\n `${relPkg} declares itself as \"${declared}\", not \"${name}\".\\n` +\n (resolved.subdir\n ? `The registry's repository.directory for \"${name}\" points at the wrong package.`\n : `${resolved.repo} is probably a monorepo. Point at the right directory:\\n` +\n ` linked localize ${name} --repo ${resolved.repo} --subdir <path-inside-the-repo>`),\n EXIT_REFUSED,\n );\n }\n\n return installLinkAndRecord(\n {\n npmName: resolved.npmName,\n clone,\n relPkg,\n pkgDir,\n repo: resolved.repo,\n subdir: resolved.subdir,\n },\n opts,\n deps,\n code,\n );\n}\n\n/**\n * Everything after the checkout exists, shared by `localize` and `adopt`:\n * install inside it, run the configured build, link it, and describe the\n * manifest entry. Nothing here knows how the checkout got there.\n *\n * `repo` may be absent -- an adopted checkout with no remote is recorded\n * without one.\n */\nexport function installLinkAndRecord(\n {\n npmName,\n clone,\n relPkg,\n pkgDir,\n repo,\n subdir,\n }: {\n npmName: string;\n clone: string;\n relPkg: string;\n pkgDir: string;\n repo?: string;\n subdir?: string;\n },\n opts: LocalizeOptions,\n deps: Deps,\n code = 0,\n): {code: number; entry: {name: string; value: ManifestEntry}} {\n // THE constraint. Read the module header before changing this. `ensure`\n // installs inside the checkout and prunes it as one step (ensure.ts).\n try {\n code = Math.max(code, ensure({path: relPkg, subdir}, deps, opts));\n } catch (e) {\n if (e instanceof LocalizeError && e.code === EXIT_INSTALL_FAILED)\n e.message += `\\nThe checkout is left on disk. Nothing was linked and nothing was recorded.`;\n throw e;\n }\n\n // The build is the one thing localize does not know how to do, so it is\n // configuration rather than behaviour. A failure is a WARNING: a package\n // whose build is broken is exactly what you are about to fix, and refusing\n // to link it would be perverse.\n if (runBuild(relPkg, pkgDir, opts, deps) === 'failed')\n code = Math.max(code, EXIT_WARNED);\n\n writeLink(deps.appRoot, npmName, pkgDir);\n const branch = currentBranch(clone, deps);\n deps.log(`[localize] linked ${npmName} -> ${relPkg} (branch ${branch})`);\n\n const range = declaredRange(npmName, deps);\n return {\n code,\n entry: {\n name: npmName,\n value: {\n ...(repo ? {repo} : {}),\n path: relPkg,\n branch,\n ...(subdir ? {subdir} : {}),\n ...(range ? {range} : {}),\n // `--no-prune` is remembered, so the run-time check and `--relink` honour it too.\n ...(shouldPrune(opts) ? {} : {prune: false as const}),\n },\n },\n };\n}\n\n/**\n * A registry lookup that fails while a git checkout already sits where the\n * clone would go is almost always a package that was never published -- one\n * made locally. Say how to link it as it is rather than leave the developer\n * guessing at a `--repo`.\n */\nfunction resolveOrSuggestAdopt(name, dir, override, deps) {\n try {\n return resolvePackage(name, deps, override);\n } catch (e) {\n const relClone = path.join(dir, checkoutNameFor(name));\n if (\n e instanceof LocalizeError &&\n e.code === EXIT_NOT_FOUND &&\n isGitCheckout(path.join(deps.appRoot, relClone))\n ) {\n e.message +=\n `\\n${relClone} is already a git checkout. To link it as it is, with no registry lookup:\\n` +\n ` linked localize ${name} --adopt`;\n }\n throw e;\n }\n}\n\n/** Older manifests recorded `owner/repo`; those are re-resolved rather than cloned blind. */\nfunction looksLikeOrgSlug(repo) {\n return /^[\\w.-]+\\/[\\w.-]+$/.test(repo);\n}\n\n/**\n * Reuse an existing clone. A dirty tree is reused WITHOUT pulling and said so;\n * a clean one is fast-forwarded; a non-fast-forward is reported and skipped\n * rather than forced, because the developer's commits are the entire point.\n */\nfunction refresh(relPath, clone, deps) {\n const status = deps.run('git', ['status', '--porcelain'], {cwd: clone});\n const modified = status.stdout.split('\\n').filter((l) => l.trim()).length;\n if (modified > 0) {\n deps.log(\n `[localize] ${relPath}: ${modified} modified file${modified === 1 ? '' : 's'} — not pulling`,\n );\n return 0;\n }\n const pull = deps.run('git', ['pull', '--ff-only'], {cwd: clone});\n if (pull.status !== 0) {\n deps.warn(\n `[localize] ${relPath}: \\`git pull --ff-only\\` failed (not a fast-forward) — skipped, not ` +\n `forced. Reconcile it by hand:\\n${(pull.stderr || pull.stdout).trim()}`,\n );\n return EXIT_WARNED;\n }\n return 0;\n}\n\n/**\n * Run the configured build command, if there is one.\n *\n * localize has no opinion about how a checkout is built, and does not look for\n * a builder. `--build \"<cmd>\"`, or a `build` field in the manifest, or\n * `{build}` in the programmatic options. Absent -- the common case, and the\n * case for anything whose dev loop reads source directly -- nothing runs and\n * nothing is said.\n */\nfunction runBuild(relPath, pkgDir, opts, deps) {\n const cmd = opts.build;\n if (!cmd) return 'skipped';\n deps.log(`[localize] ${relPath}: ${cmd}`);\n const r = deps.run(cmd, [], {cwd: pkgDir, shell: true});\n if (r.status !== 0) {\n deps.warn(\n `[localize] ${relPath}: \\`${cmd}\\` failed. The package is linked and recorded anyway — ` +\n `a package whose build is broken is exactly what you are about to fix.\\n` +\n `${(r.stderr || r.stdout).trim()}`,\n );\n return 'failed';\n }\n return 'ok';\n}\n\n/** Refuse when `node_modules/<name>` is already a symlink pointing outside `<dir>`. */\nexport function guardForeignLink(\n npmName: string,\n dir: string,\n opts: {force?: boolean},\n deps: Deps,\n): void {\n const link = path.join(deps.appRoot, 'node_modules', npmName);\n if (!isSymlink(link)) return;\n let target;\n try {\n target = fs.realpathSync(link);\n } catch {\n return; // a dangling link is ours to replace\n }\n if (isInside(target, path.join(deps.appRoot, dir))) return;\n if (opts.force) {\n deps.warn(\n `[localize] --force: overwriting the existing link ${npmName} -> ${target}`,\n );\n return;\n }\n throw new LocalizeError(\n `node_modules/${npmName} is already a symlink to ${target}, which is outside ${dir}.\\n` +\n `Refusing to overwrite someone else's link. Pass --force to replace it.`,\n EXIT_REFUSED,\n );\n}\n\n/** Every recorded package is actually linked where the manifest says it is. */\nfunction assertLinked(entries: Record<string, ManifestEntry>, deps: Deps) {\n let code = 0;\n for (const [name, entry] of Object.entries(entries)) {\n const link = path.join(deps.appRoot, 'node_modules', name);\n const expected = path.join(deps.appRoot, entry.path);\n if (!isSymlink(link)) {\n deps.warn(\n `[localize] ${name} is recorded but node_modules/${name} is not a symlink.`,\n );\n code = Math.max(code, EXIT_WARNED);\n continue;\n }\n if (!fs.existsSync(expected)) continue; // \"checkout missing\" is a --list state, not a failure\n if (fs.realpathSync(link) !== fs.realpathSync(expected)) {\n deps.warn(\n `[localize] ${name} links to ${fs.realpathSync(link)} but the manifest records ${entry.path}.`,\n );\n code = Math.max(code, EXIT_WARNED);\n }\n }\n return code;\n}\n\n/**\n * The property the whole design rests on: this run changed neither manifest.\n *\n * Content hashes, not `git status`. `git status` compares against HEAD, so in\n * any tree with an uncommitted `package.json` it reports a modification the\n * command did not make -- an earlier tool shipped exactly that and reported\n * correct runs as failures.\n */\nexport function assertManifestsUntouched(\n before: Record<string, string | null>,\n deps: Deps,\n): number {\n const changed = diffManifests(before, snapshotManifests(deps.appRoot));\n if (!changed.length) return 0;\n deps.error(\n `[localize] the consumer's manifests changed while this command ran:\\n` +\n changed.map((c) => ` ${c}`).join('\\n') +\n `\\nThis is the exact failure localize exists to prevent. Revert those files; nothing in ` +\n `localize is supposed to touch them.`,\n );\n return EXIT_MANIFEST_DIRTY;\n}\n\nexport function reportError(e: unknown, deps: Pick<Deps, 'error'>): number {\n if (e instanceof LocalizeError) {\n deps.error(`[localize] ${e.message}`);\n return e.code;\n }\n throw e;\n}\n\n/**\n * The checked-out branch, or `HEAD` when detached. `symbolic-ref` first,\n * because it also names the branch of a repository with no commits yet --\n * `rev-parse --abbrev-ref` fails there, and `create-package` adopts a fresh\n * `git init` before its first commit.\n */\nexport function currentBranch(clone: string, deps: Deps): string {\n const sym = deps.run('git', ['symbolic-ref', '--short', '-q', 'HEAD'], {\n cwd: clone,\n });\n if (sym.status === 0 && sym.stdout.trim()) return sym.stdout.trim();\n const r = deps.run('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd: clone,\n });\n const b = r.stdout.trim();\n return r.status === 0 && b ? b : 'HEAD';\n}\n\nexport function declaredRange(\n name: string,\n deps: Pick<Deps, 'appRoot'>,\n): string | undefined {\n const pkg = readJson(path.join(deps.appRoot, 'package.json'));\n if (!pkg) return undefined;\n return (\n pkg.dependencies?.[name] ??\n pkg.devDependencies?.[name] ??\n pkg.optionalDependencies?.[name]\n );\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PackageKind } from './packageKind.js';
|
|
1
2
|
export declare const PACKAGE_LOCATIONS: readonly ["packages", "packages-local"];
|
|
2
3
|
export type PackageLocation = (typeof PACKAGE_LOCATIONS)[number];
|
|
3
4
|
export interface CreatePackageOptions {
|
|
@@ -7,6 +8,18 @@ export interface CreatePackageOptions {
|
|
|
7
8
|
remote?: string;
|
|
8
9
|
/** Push the initial commit. Needs `remote`. */
|
|
9
10
|
push?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* What to scaffold: an ontology package, an asset package or both. See
|
|
13
|
+
* `./packageKind.js`. Validated at runtime too.
|
|
14
|
+
*/
|
|
15
|
+
kind?: PackageKind;
|
|
16
|
+
/** Write the files only: no install, no build, no git. */
|
|
17
|
+
skipInstall?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* The root the package's IRIs are minted under. Inside an app it defaults to the
|
|
20
|
+
* app's `LINKED_BASE_URI`; see `./packageBaseUri.js`.
|
|
21
|
+
*/
|
|
22
|
+
baseUri?: string;
|
|
10
23
|
}
|
|
11
24
|
/**
|
|
12
25
|
* - `outside`: no app above us — the old behaviour, unchanged.
|
|
@@ -60,12 +73,14 @@ export declare function ensureWorkspaceGlob(pkg: Record<string, any>): {
|
|
|
60
73
|
changed: boolean;
|
|
61
74
|
warning?: string;
|
|
62
75
|
};
|
|
63
|
-
export
|
|
76
|
+
export { RELINK_COMMAND, ensureRelinkHooks } from './relinkHooks.js';
|
|
64
77
|
/**
|
|
65
|
-
* Make sure the app's `postinstall`
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
78
|
+
* Make sure the app's `postinstall` AND `dependencies` scripts recreate
|
|
79
|
+
* localize's links -- see `./relinkHooks.js` for why npm needs both. Kept
|
|
80
|
+
* under its old name for existing callers; prefer `ensureRelinkHooks`.
|
|
81
|
+
* Mutates `pkg`.
|
|
82
|
+
*
|
|
83
|
+
* @returns true when it changed `pkg`.
|
|
69
84
|
*/
|
|
70
85
|
export declare function ensureRelinkPostinstall(pkg: Record<string, any>): boolean;
|
|
71
86
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPackageLocation.d.ts","sourceRoot":"","sources":["../../../src/utils/createPackageLocation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createPackageLocation.d.ts","sourceRoot":"","sources":["../../../src/utils/createPackageLocation.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAGlD,eAAO,MAAM,iBAAiB,yCAA0C,CAAC;AACzE,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GACtB;IAAC,IAAI,EAAE,SAAS,CAAA;CAAC,GACjB;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,GAC7E;IAAC,IAAI,EAAE,KAAK,CAAA;CAAC,GACb;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC;AAEtC,gEAAgE;AAChE,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB9D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,OAAO,EACP,OAAO,EACP,KAAK,GACN,EAAE;IACD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,cAAc,CAwCjB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,eAAe,CAEzE;AAMD,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM7C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAC7D,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAsBA;AAED,OAAO,EAAC,cAAc,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAEnE;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAEzE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOvD"}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import fs from 'fs';
|
|
15
15
|
import path from 'path';
|
|
16
|
+
import { ensureRelinkHooks } from './relinkHooks.js';
|
|
16
17
|
export const PACKAGE_LOCATIONS = ['packages', 'packages-local'];
|
|
17
18
|
/** A refusal of create-package's own, as opposed to a crash. */
|
|
18
19
|
export class CreatePackageError extends Error {
|
|
@@ -121,23 +122,17 @@ export function ensureWorkspaceGlob(pkg) {
|
|
|
121
122
|
globs.push('packages/*');
|
|
122
123
|
return { changed: true };
|
|
123
124
|
}
|
|
124
|
-
export
|
|
125
|
+
export { RELINK_COMMAND, ensureRelinkHooks } from './relinkHooks.js';
|
|
125
126
|
/**
|
|
126
|
-
* Make sure the app's `postinstall`
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
127
|
+
* Make sure the app's `postinstall` AND `dependencies` scripts recreate
|
|
128
|
+
* localize's links -- see `./relinkHooks.js` for why npm needs both. Kept
|
|
129
|
+
* under its old name for existing callers; prefer `ensureRelinkHooks`.
|
|
130
|
+
* Mutates `pkg`.
|
|
131
|
+
*
|
|
132
|
+
* @returns true when it changed `pkg`.
|
|
130
133
|
*/
|
|
131
134
|
export function ensureRelinkPostinstall(pkg) {
|
|
132
|
-
|
|
133
|
-
pkg.scripts = (_a = pkg.scripts) !== null && _a !== void 0 ? _a : {};
|
|
134
|
-
const current = pkg.scripts.postinstall;
|
|
135
|
-
if (current && /localize\s+--relink/.test(current))
|
|
136
|
-
return false;
|
|
137
|
-
pkg.scripts.postinstall = current
|
|
138
|
-
? `${current} && ${RELINK_COMMAND}`
|
|
139
|
-
: RELINK_COMMAND;
|
|
140
|
-
return true;
|
|
135
|
+
return ensureRelinkHooks(pkg).length > 0;
|
|
141
136
|
}
|
|
142
137
|
/**
|
|
143
138
|
* A git remote as npm wants it in `repository.url`: `git+https://…`, or
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPackageLocation.js","sourceRoot":"","sources":["../../../src/utils/createPackageLocation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Where `linked create-package` puts a new package, decided without touching\n * anything — the IO lives in `createPackage`.\n *\n * Inside an app there are two homes, and they mean different things:\n *\n * - `packages/` — the package is part of the app's own repository: a tracked\n * npm workspace member, declared as a dependency like any other.\n * - `packages-local/` — the package has a repository of its own. It goes where\n * `linked localize` keeps checkouts, under the same name localize would give\n * it (`@_linked/foo` → `packages-local/_linked-foo`), and is handed to\n * localize's `adopt`, so the two can never disagree about it.\n */\nimport fs from 'fs';\nimport path from 'path';\n\nexport const PACKAGE_LOCATIONS = ['packages', 'packages-local'] as const;\nexport type PackageLocation = (typeof PACKAGE_LOCATIONS)[number];\n\nexport interface CreatePackageOptions {\n /** Validated at runtime too, since the command line passes any string. */\n location?: PackageLocation;\n /** A git URL. Implies `packages-local`. */\n remote?: string;\n /** Push the initial commit. Needs `remote`. */\n push?: boolean;\n}\n\n/**\n * - `outside`: no app above us — the old behaviour, unchanged.\n * - `resolved`: the flags (or the prompt's answers) settle it.\n * - `ask`: inside an app, no flags, on a terminal.\n * - `refuse`: a contradiction, or no answer and no terminal to ask.\n */\nexport type TargetDecision =\n | {kind: 'outside'}\n | {kind: 'resolved'; location: PackageLocation; remote?: string; push: boolean}\n | {kind: 'ask'}\n | {kind: 'refuse'; message: string};\n\n/** A refusal of create-package's own, as opposed to a crash. */\nexport class CreatePackageError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CreatePackageError';\n }\n}\n\n/**\n * The nearest directory, from `start` upwards, whose package.json says\n * `linkedApp: true`. That is the app — whether or not it has `workspaces`,\n * which the app template does not.\n */\nexport function findLinkedAppRoot(start: string): string | null {\n let dir = path.resolve(start);\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n const pkg = JSON.parse(\n fs.readFileSync(path.join(dir, 'package.json'), 'utf8'),\n );\n if (pkg?.linkedApp === true) return dir;\n } catch {\n // no package.json here, or not one we can read: keep walking\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Flags decide everything they can. Any of `--location`, `--remote` or\n * `--push` is taken as the complete answer, so a scripted call never meets a\n * prompt; with none of them, a terminal is asked and anything else is refused.\n */\nexport function decideCreatePackageTarget({\n appRoot,\n options,\n isTTY,\n}: {\n appRoot: string | null;\n options: CreatePackageOptions;\n isTTY: boolean;\n}): TargetDecision {\n const {remote, push = false} = options;\n const location: string | undefined = options.location;\n const given = location !== undefined || remote !== undefined || push;\n\n if (location !== undefined && !isPackageLocation(location)) {\n return refuse(\n `--location must be one of ${PACKAGE_LOCATIONS.join(', ')}, not \"${location}\".`,\n );\n }\n if (!appRoot) {\n return given\n ? refuse(\n `--location, --remote and --push only apply inside a linked app, and no package.json ` +\n `with \"linkedApp\": true was found above this directory.`,\n )\n : {kind: 'outside'};\n }\n if (push && !remote) {\n return refuse('--push needs --remote: there is nowhere to push to.');\n }\n if (remote && location === 'packages') {\n return refuse(\n `--remote gives the package a repository of its own, but packages/ is for packages that ` +\n `live in the app's repository. Use --location packages-local, or drop --remote.`,\n );\n }\n if (given) {\n return {\n kind: 'resolved',\n location: (location as PackageLocation) ?? 'packages-local',\n ...(remote ? {remote} : {}),\n push,\n };\n }\n if (isTTY) return {kind: 'ask'};\n return refuse(\n `Where should the package go? Pass --location packages (part of this app's repository) or ` +\n `--location packages-local (its own repository, optionally with --remote <git-url>).`,\n );\n}\n\nexport function isPackageLocation(value: string): value is PackageLocation {\n return (PACKAGE_LOCATIONS as readonly string[]).includes(value);\n}\n\nfunction refuse(message: string): TargetDecision {\n return {kind: 'refuse', message};\n}\n\n/** `@scope/foo-bar` → `foo-bar`: the folder name under `packages/`. */\nexport function bareName(name: string): string {\n const match = name.match(/(@[\\w\\-]+\\/)?([\\w\\-]+)/);\n if (!match) {\n throw new CreatePackageError(`\"${name}\" is not a usable package name.`);\n }\n return match[2];\n}\n\n/**\n * Make sure the app's `workspaces` covers `packages/*`, so a package created\n * there is a workspace member. Mutates `pkg`.\n *\n * @returns whether it changed, and a warning when it cannot tell.\n */\nexport function ensureWorkspaceGlob(pkg: Record<string, any>): {\n changed: boolean;\n warning?: string;\n} {\n const covers = (globs: unknown[]) =>\n globs.some((g) => g === 'packages/*' || g === 'packages/**');\n\n if (pkg.workspaces === undefined) {\n pkg.workspaces = ['packages/*'];\n return {changed: true};\n }\n const globs = Array.isArray(pkg.workspaces)\n ? pkg.workspaces\n : Array.isArray(pkg.workspaces?.packages)\n ? pkg.workspaces.packages\n : null;\n if (!globs) {\n return {\n changed: false,\n warning: `the app's \"workspaces\" field has a shape this command does not edit; make sure it covers packages/*.`,\n };\n }\n if (covers(globs)) return {changed: false};\n globs.push('packages/*');\n return {changed: true};\n}\n\nexport const RELINK_COMMAND = 'linked localize --relink';\n\n/**\n * Make sure the app's `postinstall` recreates localize's links. Without it the\n * next `npm install` prunes a packages-local link as extraneous. With no\n * `local-packages.json` the hook prints nothing and exits 0, so it is safe to\n * commit for everyone. Mutates `pkg`.\n */\nexport function ensureRelinkPostinstall(pkg: Record<string, any>): boolean {\n pkg.scripts = pkg.scripts ?? {};\n const current: string | undefined = pkg.scripts.postinstall;\n if (current && /localize\\s+--relink/.test(current)) return false;\n pkg.scripts.postinstall = current\n ? `${current} && ${RELINK_COMMAND}`\n : RELINK_COMMAND;\n return true;\n}\n\n/**\n * A git remote as npm wants it in `repository.url`: `git+https://…`, or\n * `git+ssh://git@host/path` for the scp-like `git@host:path` form.\n */\nexport function repositoryUrlFor(remote: string): string {\n const url = remote.trim();\n if (url.startsWith('git+')) return url;\n const scp = /^([\\w.-]+@[\\w.-]+):(?!\\/)(.+)$/.exec(url);\n if (scp) return `git+ssh://${scp[1]}/${scp[2]}`;\n if (/^(https?|ssh):\\/\\//.test(url)) return `git+${url}`;\n return url;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createPackageLocation.js","sourceRoot":"","sources":["../../../src/utils/createPackageLocation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Where `linked create-package` puts a new package, decided without touching\n * anything — the IO lives in `createPackage`.\n *\n * Inside an app there are two homes, and they mean different things:\n *\n * - `packages/` — the package is part of the app's own repository: a tracked\n * npm workspace member, declared as a dependency like any other.\n * - `packages-local/` — the package has a repository of its own. It goes where\n * `linked localize` keeps checkouts, under the same name localize would give\n * it (`@_linked/foo` → `packages-local/_linked-foo`), and is handed to\n * localize's `adopt`, so the two can never disagree about it.\n */\nimport fs from 'fs';\nimport path from 'path';\nimport type {PackageKind} from './packageKind.js';\nimport {ensureRelinkHooks} from './relinkHooks.js';\n\nexport const PACKAGE_LOCATIONS = ['packages', 'packages-local'] as const;\nexport type PackageLocation = (typeof PACKAGE_LOCATIONS)[number];\n\nexport interface CreatePackageOptions {\n /** Validated at runtime too, since the command line passes any string. */\n location?: PackageLocation;\n /** A git URL. Implies `packages-local`. */\n remote?: string;\n /** Push the initial commit. Needs `remote`. */\n push?: boolean;\n /**\n * What to scaffold: an ontology package, an asset package or both. See\n * `./packageKind.js`. Validated at runtime too.\n */\n kind?: PackageKind;\n /** Write the files only: no install, no build, no git. */\n skipInstall?: boolean;\n /**\n * The root the package's IRIs are minted under. Inside an app it defaults to the\n * app's `LINKED_BASE_URI`; see `./packageBaseUri.js`.\n */\n baseUri?: string;\n}\n\n/**\n * - `outside`: no app above us — the old behaviour, unchanged.\n * - `resolved`: the flags (or the prompt's answers) settle it.\n * - `ask`: inside an app, no flags, on a terminal.\n * - `refuse`: a contradiction, or no answer and no terminal to ask.\n */\nexport type TargetDecision =\n | {kind: 'outside'}\n | {kind: 'resolved'; location: PackageLocation; remote?: string; push: boolean}\n | {kind: 'ask'}\n | {kind: 'refuse'; message: string};\n\n/** A refusal of create-package's own, as opposed to a crash. */\nexport class CreatePackageError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CreatePackageError';\n }\n}\n\n/**\n * The nearest directory, from `start` upwards, whose package.json says\n * `linkedApp: true`. That is the app — whether or not it has `workspaces`,\n * which the app template does not.\n */\nexport function findLinkedAppRoot(start: string): string | null {\n let dir = path.resolve(start);\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n const pkg = JSON.parse(\n fs.readFileSync(path.join(dir, 'package.json'), 'utf8'),\n );\n if (pkg?.linkedApp === true) return dir;\n } catch {\n // no package.json here, or not one we can read: keep walking\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Flags decide everything they can. Any of `--location`, `--remote` or\n * `--push` is taken as the complete answer, so a scripted call never meets a\n * prompt; with none of them, a terminal is asked and anything else is refused.\n */\nexport function decideCreatePackageTarget({\n appRoot,\n options,\n isTTY,\n}: {\n appRoot: string | null;\n options: CreatePackageOptions;\n isTTY: boolean;\n}): TargetDecision {\n const {remote, push = false} = options;\n const location: string | undefined = options.location;\n const given = location !== undefined || remote !== undefined || push;\n\n if (location !== undefined && !isPackageLocation(location)) {\n return refuse(\n `--location must be one of ${PACKAGE_LOCATIONS.join(', ')}, not \"${location}\".`,\n );\n }\n if (!appRoot) {\n return given\n ? refuse(\n `--location, --remote and --push only apply inside a linked app, and no package.json ` +\n `with \"linkedApp\": true was found above this directory.`,\n )\n : {kind: 'outside'};\n }\n if (push && !remote) {\n return refuse('--push needs --remote: there is nowhere to push to.');\n }\n if (remote && location === 'packages') {\n return refuse(\n `--remote gives the package a repository of its own, but packages/ is for packages that ` +\n `live in the app's repository. Use --location packages-local, or drop --remote.`,\n );\n }\n if (given) {\n return {\n kind: 'resolved',\n location: (location as PackageLocation) ?? 'packages-local',\n ...(remote ? {remote} : {}),\n push,\n };\n }\n if (isTTY) return {kind: 'ask'};\n return refuse(\n `Where should the package go? Pass --location packages (part of this app's repository) or ` +\n `--location packages-local (its own repository, optionally with --remote <git-url>).`,\n );\n}\n\nexport function isPackageLocation(value: string): value is PackageLocation {\n return (PACKAGE_LOCATIONS as readonly string[]).includes(value);\n}\n\nfunction refuse(message: string): TargetDecision {\n return {kind: 'refuse', message};\n}\n\n/** `@scope/foo-bar` → `foo-bar`: the folder name under `packages/`. */\nexport function bareName(name: string): string {\n const match = name.match(/(@[\\w\\-]+\\/)?([\\w\\-]+)/);\n if (!match) {\n throw new CreatePackageError(`\"${name}\" is not a usable package name.`);\n }\n return match[2];\n}\n\n/**\n * Make sure the app's `workspaces` covers `packages/*`, so a package created\n * there is a workspace member. Mutates `pkg`.\n *\n * @returns whether it changed, and a warning when it cannot tell.\n */\nexport function ensureWorkspaceGlob(pkg: Record<string, any>): {\n changed: boolean;\n warning?: string;\n} {\n const covers = (globs: unknown[]) =>\n globs.some((g) => g === 'packages/*' || g === 'packages/**');\n\n if (pkg.workspaces === undefined) {\n pkg.workspaces = ['packages/*'];\n return {changed: true};\n }\n const globs = Array.isArray(pkg.workspaces)\n ? pkg.workspaces\n : Array.isArray(pkg.workspaces?.packages)\n ? pkg.workspaces.packages\n : null;\n if (!globs) {\n return {\n changed: false,\n warning: `the app's \"workspaces\" field has a shape this command does not edit; make sure it covers packages/*.`,\n };\n }\n if (covers(globs)) return {changed: false};\n globs.push('packages/*');\n return {changed: true};\n}\n\nexport {RELINK_COMMAND, ensureRelinkHooks} from './relinkHooks.js';\n\n/**\n * Make sure the app's `postinstall` AND `dependencies` scripts recreate\n * localize's links -- see `./relinkHooks.js` for why npm needs both. Kept\n * under its old name for existing callers; prefer `ensureRelinkHooks`.\n * Mutates `pkg`.\n *\n * @returns true when it changed `pkg`.\n */\nexport function ensureRelinkPostinstall(pkg: Record<string, any>): boolean {\n return ensureRelinkHooks(pkg).length > 0;\n}\n\n/**\n * A git remote as npm wants it in `repository.url`: `git+https://…`, or\n * `git+ssh://git@host/path` for the scp-like `git@host:path` form.\n */\nexport function repositoryUrlFor(remote: string): string {\n const url = remote.trim();\n if (url.startsWith('git+')) return url;\n const scp = /^([\\w.-]+@[\\w.-]+):(?!\\/)(.+)$/.exec(url);\n if (scp) return `git+ssh://${scp[1]}/${scp[2]}`;\n if (/^(https?|ssh):\\/\\//.test(url)) return `git+${url}`;\n return url;\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const BASE_URI_ENV = "LINKED_BASE_URI";
|
|
2
|
+
export type BaseUriSource = '--base-uri' | 'environment' | '.env.local' | '.env';
|
|
3
|
+
export interface ResolvedBaseUri {
|
|
4
|
+
baseUri: string;
|
|
5
|
+
source: BaseUriSource;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A root as IRIs are appended to it: absolute http(s), no query or fragment,
|
|
9
|
+
* ending in `/`. Mirrors the app template's `resolveBaseUri`. Empty → undefined.
|
|
10
|
+
*/
|
|
11
|
+
export declare function normalizeBaseUri(value: string | undefined, from: string): string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* The base URI for a package created in `appRoot` (null outside an app, where
|
|
14
|
+
* only the flag counts). Undefined when no source sets one.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolvePackageBaseUri({ flag, appRoot, env, }: {
|
|
17
|
+
flag?: string;
|
|
18
|
+
appRoot: string | null;
|
|
19
|
+
env?: NodeJS.ProcessEnv;
|
|
20
|
+
}): ResolvedBaseUri | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Give a scaffolded `src/package.ts` its root: `linkedPackage('x')` →
|
|
23
|
+
* `linkedPackage('x', {baseUri: '…'})`. Throws when the call is not found, so a
|
|
24
|
+
* template change cannot silently drop the root.
|
|
25
|
+
*/
|
|
26
|
+
export declare function withBaseUri(packageTs: string, baseUri: string): string;
|
|
27
|
+
//# sourceMappingURL=packageBaseUri.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageBaseUri.d.ts","sourceRoot":"","sources":["../../../src/utils/packageBaseUri.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,YAAY,oBAAoB,CAAC;AAE9C,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,aAAa,GAAG,YAAY,GAAG,MAAM,CAAC;AAEjF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAwB5F;AAQD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,OAAO,EACP,GAAiB,GAClB,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GAAG,eAAe,GAAG,SAAS,CAc9B;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAMtE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The root a new package's IRIs are minted under: `linkedPackage(name, {baseUri})`
|
|
3
|
+
* gives shapes `{baseUri}shape/{slug}/{Name}`, and an ontology package's terms are
|
|
4
|
+
* `{baseUri}ont/{ontologySlug}/{Term}`. Without one, core's default
|
|
5
|
+
* (`https://linked.cm/`) applies.
|
|
6
|
+
*
|
|
7
|
+
* Where it comes from, first match wins:
|
|
8
|
+
*
|
|
9
|
+
* 1. `--base-uri <uri>`: explicit, and what a script or a host passes.
|
|
10
|
+
* 2. `LINKED_BASE_URI` in the shell environment.
|
|
11
|
+
* 3. `LINKED_BASE_URI` in the app's `.env.local`, then its `.env`.
|
|
12
|
+
*
|
|
13
|
+
* 2 and 3 are the variable the app template documents as "the root of this
|
|
14
|
+
* app's package and shape IRIs", read with the same precedence `linked start`
|
|
15
|
+
* gives the app's `.env` (the shell wins over the file). The file is parsed, not
|
|
16
|
+
* loaded, so creating a package never changes this process's environment.
|
|
17
|
+
* `linked.config.js` is not a source: it is a module that would have to be
|
|
18
|
+
* imported (running the app's code) just to scaffold a package, and it has no
|
|
19
|
+
* IRI setting today.
|
|
20
|
+
*/
|
|
21
|
+
import fs from 'fs';
|
|
22
|
+
import path from 'path';
|
|
23
|
+
import { parseEnv } from 'util';
|
|
24
|
+
export const BASE_URI_ENV = 'LINKED_BASE_URI';
|
|
25
|
+
/**
|
|
26
|
+
* A root as IRIs are appended to it: absolute http(s), no query or fragment,
|
|
27
|
+
* ending in `/`. Mirrors the app template's `resolveBaseUri`. Empty → undefined.
|
|
28
|
+
*/
|
|
29
|
+
export function normalizeBaseUri(value, from) {
|
|
30
|
+
const trimmed = value === null || value === void 0 ? void 0 : value.trim();
|
|
31
|
+
if (!trimmed)
|
|
32
|
+
return undefined;
|
|
33
|
+
let url;
|
|
34
|
+
try {
|
|
35
|
+
url = new URL(trimmed);
|
|
36
|
+
}
|
|
37
|
+
catch (_a) {
|
|
38
|
+
url = undefined;
|
|
39
|
+
}
|
|
40
|
+
if (!url ||
|
|
41
|
+
!/^https?:$/.test(url.protocol) ||
|
|
42
|
+
!url.hostname ||
|
|
43
|
+
url.search ||
|
|
44
|
+
url.hash ||
|
|
45
|
+
/\s/.test(trimmed) ||
|
|
46
|
+
trimmed.includes('?') ||
|
|
47
|
+
trimmed.includes('#')) {
|
|
48
|
+
throw new Error(`${from} must be an absolute http(s) URI without a query or fragment, got ${JSON.stringify(value)}`);
|
|
49
|
+
}
|
|
50
|
+
return trimmed.endsWith('/') ? trimmed : `${trimmed}/`;
|
|
51
|
+
}
|
|
52
|
+
/** `LINKED_BASE_URI` from an env file, or undefined when the file or the key is absent. */
|
|
53
|
+
function fromEnvFile(file) {
|
|
54
|
+
if (!fs.existsSync(file))
|
|
55
|
+
return undefined;
|
|
56
|
+
return parseEnv(fs.readFileSync(file, 'utf8'))[BASE_URI_ENV];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The base URI for a package created in `appRoot` (null outside an app, where
|
|
60
|
+
* only the flag counts). Undefined when no source sets one.
|
|
61
|
+
*/
|
|
62
|
+
export function resolvePackageBaseUri({ flag, appRoot, env = process.env, }) {
|
|
63
|
+
const fromFlag = normalizeBaseUri(flag, '--base-uri');
|
|
64
|
+
if (fromFlag)
|
|
65
|
+
return { baseUri: fromFlag, source: '--base-uri' };
|
|
66
|
+
if (!appRoot)
|
|
67
|
+
return undefined;
|
|
68
|
+
const fromShell = normalizeBaseUri(env[BASE_URI_ENV], BASE_URI_ENV);
|
|
69
|
+
if (fromShell)
|
|
70
|
+
return { baseUri: fromShell, source: 'environment' };
|
|
71
|
+
for (const name of ['.env.local', '.env']) {
|
|
72
|
+
const file = path.join(appRoot, name);
|
|
73
|
+
const value = normalizeBaseUri(fromEnvFile(file), `${BASE_URI_ENV} in ${file}`);
|
|
74
|
+
if (value)
|
|
75
|
+
return { baseUri: value, source: name };
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Give a scaffolded `src/package.ts` its root: `linkedPackage('x')` →
|
|
81
|
+
* `linkedPackage('x', {baseUri: '…'})`. Throws when the call is not found, so a
|
|
82
|
+
* template change cannot silently drop the root.
|
|
83
|
+
*/
|
|
84
|
+
export function withBaseUri(packageTs, baseUri) {
|
|
85
|
+
const call = /linkedPackage\(\s*(['"][^'"]+['"])\s*\)/;
|
|
86
|
+
if (!call.test(packageTs)) {
|
|
87
|
+
throw new Error('src/package.ts has no linkedPackage(<name>) call to give a baseUri to.');
|
|
88
|
+
}
|
|
89
|
+
return packageTs.replace(call, `linkedPackage($1, {baseUri: ${JSON.stringify(baseUri)}})`);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=packageBaseUri.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageBaseUri.js","sourceRoot":"","sources":["../../../src/utils/packageBaseUri.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The root a new package's IRIs are minted under: `linkedPackage(name, {baseUri})`\n * gives shapes `{baseUri}shape/{slug}/{Name}`, and an ontology package's terms are\n * `{baseUri}ont/{ontologySlug}/{Term}`. Without one, core's default\n * (`https://linked.cm/`) applies.\n *\n * Where it comes from, first match wins:\n *\n * 1. `--base-uri <uri>`: explicit, and what a script or a host passes.\n * 2. `LINKED_BASE_URI` in the shell environment.\n * 3. `LINKED_BASE_URI` in the app's `.env.local`, then its `.env`.\n *\n * 2 and 3 are the variable the app template documents as \"the root of this\n * app's package and shape IRIs\", read with the same precedence `linked start`\n * gives the app's `.env` (the shell wins over the file). The file is parsed, not\n * loaded, so creating a package never changes this process's environment.\n * `linked.config.js` is not a source: it is a module that would have to be\n * imported (running the app's code) just to scaffold a package, and it has no\n * IRI setting today.\n */\nimport fs from 'fs';\nimport path from 'path';\nimport {parseEnv} from 'util';\n\nexport const BASE_URI_ENV = 'LINKED_BASE_URI';\n\nexport type BaseUriSource = '--base-uri' | 'environment' | '.env.local' | '.env';\n\nexport interface ResolvedBaseUri {\n baseUri: string;\n source: BaseUriSource;\n}\n\n/**\n * A root as IRIs are appended to it: absolute http(s), no query or fragment,\n * ending in `/`. Mirrors the app template's `resolveBaseUri`. Empty → undefined.\n */\nexport function normalizeBaseUri(value: string | undefined, from: string): string | undefined {\n const trimmed = value?.trim();\n if (!trimmed) return undefined;\n let url: URL;\n try {\n url = new URL(trimmed);\n } catch {\n url = undefined;\n }\n if (\n !url ||\n !/^https?:$/.test(url.protocol) ||\n !url.hostname ||\n url.search ||\n url.hash ||\n /\\s/.test(trimmed) ||\n trimmed.includes('?') ||\n trimmed.includes('#')\n ) {\n throw new Error(\n `${from} must be an absolute http(s) URI without a query or fragment, got ${JSON.stringify(value)}`,\n );\n }\n return trimmed.endsWith('/') ? trimmed : `${trimmed}/`;\n}\n\n/** `LINKED_BASE_URI` from an env file, or undefined when the file or the key is absent. */\nfunction fromEnvFile(file: string): string | undefined {\n if (!fs.existsSync(file)) return undefined;\n return parseEnv(fs.readFileSync(file, 'utf8'))[BASE_URI_ENV];\n}\n\n/**\n * The base URI for a package created in `appRoot` (null outside an app, where\n * only the flag counts). Undefined when no source sets one.\n */\nexport function resolvePackageBaseUri({\n flag,\n appRoot,\n env = process.env,\n}: {\n flag?: string;\n appRoot: string | null;\n env?: NodeJS.ProcessEnv;\n}): ResolvedBaseUri | undefined {\n const fromFlag = normalizeBaseUri(flag, '--base-uri');\n if (fromFlag) return {baseUri: fromFlag, source: '--base-uri'};\n if (!appRoot) return undefined;\n\n const fromShell = normalizeBaseUri(env[BASE_URI_ENV], BASE_URI_ENV);\n if (fromShell) return {baseUri: fromShell, source: 'environment'};\n\n for (const name of ['.env.local', '.env'] as const) {\n const file = path.join(appRoot, name);\n const value = normalizeBaseUri(fromEnvFile(file), `${BASE_URI_ENV} in ${file}`);\n if (value) return {baseUri: value, source: name};\n }\n return undefined;\n}\n\n/**\n * Give a scaffolded `src/package.ts` its root: `linkedPackage('x')` →\n * `linkedPackage('x', {baseUri: '…'})`. Throws when the call is not found, so a\n * template change cannot silently drop the root.\n */\nexport function withBaseUri(packageTs: string, baseUri: string): string {\n const call = /linkedPackage\\(\\s*(['\"][^'\"]+['\"])\\s*\\)/;\n if (!call.test(packageTs)) {\n throw new Error('src/package.ts has no linkedPackage(<name>) call to give a baseUri to.');\n }\n return packageTs.replace(call, `linkedPackage($1, {baseUri: ${JSON.stringify(baseUri)}})`);\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export declare const PACKAGE_KINDS: readonly ["ontology", "assets", "both"];
|
|
2
|
+
export type PackageKind = (typeof PACKAGE_KINDS)[number];
|
|
3
|
+
/** The kinds a single package can be: `both` expands to these two. */
|
|
4
|
+
export type ScaffoldKind = Exclude<PackageKind, 'both'>;
|
|
5
|
+
export declare const KIND_SUFFIX: Record<ScaffoldKind, string>;
|
|
6
|
+
export type KindDecision = {
|
|
7
|
+
kind: 'resolved';
|
|
8
|
+
packageKind: PackageKind;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'ask';
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'refuse';
|
|
13
|
+
message: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function isPackageKind(value: string): value is PackageKind;
|
|
16
|
+
/**
|
|
17
|
+
* `--kind` decides it. Without it a terminal is asked; anything else is
|
|
18
|
+
* refused, so a scripted call never meets a prompt. `--remote` names one
|
|
19
|
+
* repository, which cannot hold both packages.
|
|
20
|
+
*/
|
|
21
|
+
export declare function decidePackageKind({ kind, remote, isTTY, }: {
|
|
22
|
+
kind?: string;
|
|
23
|
+
remote?: string;
|
|
24
|
+
isTTY: boolean;
|
|
25
|
+
}): KindDecision;
|
|
26
|
+
/** `both` → `['ontology', 'assets']`, in the order they are created. */
|
|
27
|
+
export declare function scaffoldKinds(kind: PackageKind): ScaffoldKind[];
|
|
28
|
+
/**
|
|
29
|
+
* The package name a kind gives: `foo` → `foo-ont` / `foo-assets`, keeping an
|
|
30
|
+
* npm scope (`@acme/foo` → `@acme/foo-ont`). A name that already ends in the
|
|
31
|
+
* suffix is kept as it is, so `foo-ont` never becomes `foo-ont-ont`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function packageNameFor(name: string, kind: ScaffoldKind): string;
|
|
34
|
+
/**
|
|
35
|
+
* The ontology slug of an ontology package: the bare name without `-ont`.
|
|
36
|
+
* `@acme/foo-ont` → `foo`. It is the `{ontologySlug}` in
|
|
37
|
+
* `{root}ont/{ontologySlug}/{Term}` and the ontology's file name and prefix.
|
|
38
|
+
*/
|
|
39
|
+
export declare function ontologySlugFor(packageName: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* The template files of a kind, relative to the package root. The files every
|
|
42
|
+
* package has come from `defaults/package`; an asset package is that whole
|
|
43
|
+
* folder, an ontology package adds `defaults/package-ontology` on top of the
|
|
44
|
+
* shared files only.
|
|
45
|
+
*/
|
|
46
|
+
export declare const PACKAGE_TEMPLATE_DIRS: Record<ScaffoldKind, string[]>;
|
|
47
|
+
/** The files of `defaults/package` every kind gets. The rest is asset-only. */
|
|
48
|
+
export declare const SHARED_TEMPLATE_FILES: readonly ["gitignore.template", "npmignore.template", "package.json", "tsconfig.json", "tsconfig-esm.json", "src/package.ts"];
|
|
49
|
+
//# sourceMappingURL=packageKind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageKind.d.ts","sourceRoot":"","sources":["../../../src/utils/packageKind.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,aAAa,yCAA0C,CAAC;AACrE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,sEAAsE;AACtE,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAExD,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAGpD,CAAC;AAEF,MAAM,MAAM,YAAY,GACpB;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAC,GAC5C;IAAC,IAAI,EAAE,KAAK,CAAA;CAAC,GACb;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC;AAEtC,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,MAAM,EACN,KAAK,GACN,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,YAAY,CAkBf;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,EAAE,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CAGvE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAQ3D;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,CAGhE,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,+HAOxB,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `linked create-package` scaffolds, decided without touching anything.
|
|
3
|
+
*
|
|
4
|
+
* A linked package is one of two kinds (create-now arch-03 §Package types):
|
|
5
|
+
*
|
|
6
|
+
* - an **ontology package**, `<name>-ont`: exactly one ontology and nothing
|
|
7
|
+
* else. Its ontology slug is `<name>` (no `-ont`), so its terms mint
|
|
8
|
+
* `{root}ont/<name>/{Term}` while the package itself is `<name>-ont`.
|
|
9
|
+
* - an **asset package**, `<name>-assets`: shapes, components and a backend,
|
|
10
|
+
* and no ontology.
|
|
11
|
+
*
|
|
12
|
+
* `both` scaffolds the pair. The suffix is applied to the name given, unless
|
|
13
|
+
* the name already carries it.
|
|
14
|
+
*/
|
|
15
|
+
import { bareName } from './createPackageLocation.js';
|
|
16
|
+
export const PACKAGE_KINDS = ['ontology', 'assets', 'both'];
|
|
17
|
+
export const KIND_SUFFIX = {
|
|
18
|
+
ontology: '-ont',
|
|
19
|
+
assets: '-assets',
|
|
20
|
+
};
|
|
21
|
+
export function isPackageKind(value) {
|
|
22
|
+
return PACKAGE_KINDS.includes(value);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* `--kind` decides it. Without it a terminal is asked; anything else is
|
|
26
|
+
* refused, so a scripted call never meets a prompt. `--remote` names one
|
|
27
|
+
* repository, which cannot hold both packages.
|
|
28
|
+
*/
|
|
29
|
+
export function decidePackageKind({ kind, remote, isTTY, }) {
|
|
30
|
+
if (kind !== undefined) {
|
|
31
|
+
if (!isPackageKind(kind)) {
|
|
32
|
+
return refuse(`--kind must be one of ${PACKAGE_KINDS.join(', ')}, not "${kind}".`);
|
|
33
|
+
}
|
|
34
|
+
if (kind === 'both' && remote) {
|
|
35
|
+
return refuse(`--kind both creates two packages, and --remote names one repository. Create them ` +
|
|
36
|
+
`separately: linked create-ont-package and linked create-asset-package.`);
|
|
37
|
+
}
|
|
38
|
+
return { kind: 'resolved', packageKind: kind };
|
|
39
|
+
}
|
|
40
|
+
if (isTTY)
|
|
41
|
+
return { kind: 'ask' };
|
|
42
|
+
return refuse(`What kind of package? Pass --kind ontology (one ontology, no shapes: <name>-ont), ` +
|
|
43
|
+
`--kind assets (shapes, components and a backend: <name>-assets) or --kind both.`);
|
|
44
|
+
}
|
|
45
|
+
/** `both` → `['ontology', 'assets']`, in the order they are created. */
|
|
46
|
+
export function scaffoldKinds(kind) {
|
|
47
|
+
return kind === 'both' ? ['ontology', 'assets'] : [kind];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The package name a kind gives: `foo` → `foo-ont` / `foo-assets`, keeping an
|
|
51
|
+
* npm scope (`@acme/foo` → `@acme/foo-ont`). A name that already ends in the
|
|
52
|
+
* suffix is kept as it is, so `foo-ont` never becomes `foo-ont-ont`.
|
|
53
|
+
*/
|
|
54
|
+
export function packageNameFor(name, kind) {
|
|
55
|
+
const suffix = KIND_SUFFIX[kind];
|
|
56
|
+
return name.endsWith(suffix) ? name : `${name}${suffix}`;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The ontology slug of an ontology package: the bare name without `-ont`.
|
|
60
|
+
* `@acme/foo-ont` → `foo`. It is the `{ontologySlug}` in
|
|
61
|
+
* `{root}ont/{ontologySlug}/{Term}` and the ontology's file name and prefix.
|
|
62
|
+
*/
|
|
63
|
+
export function ontologySlugFor(packageName) {
|
|
64
|
+
const bare = bareName(packageName);
|
|
65
|
+
const suffix = KIND_SUFFIX.ontology;
|
|
66
|
+
const slug = bare.endsWith(suffix) ? bare.slice(0, -suffix.length) : bare;
|
|
67
|
+
if (!slug) {
|
|
68
|
+
throw new Error(`Cannot derive an ontology slug from '${packageName}'`);
|
|
69
|
+
}
|
|
70
|
+
return slug;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The template files of a kind, relative to the package root. The files every
|
|
74
|
+
* package has come from `defaults/package`; an asset package is that whole
|
|
75
|
+
* folder, an ontology package adds `defaults/package-ontology` on top of the
|
|
76
|
+
* shared files only.
|
|
77
|
+
*/
|
|
78
|
+
export const PACKAGE_TEMPLATE_DIRS = {
|
|
79
|
+
assets: ['package'],
|
|
80
|
+
ontology: ['package', 'package-ontology'],
|
|
81
|
+
};
|
|
82
|
+
/** The files of `defaults/package` every kind gets. The rest is asset-only. */
|
|
83
|
+
export const SHARED_TEMPLATE_FILES = [
|
|
84
|
+
'gitignore.template',
|
|
85
|
+
'npmignore.template',
|
|
86
|
+
'package.json',
|
|
87
|
+
'tsconfig.json',
|
|
88
|
+
'tsconfig-esm.json',
|
|
89
|
+
'src/package.ts',
|
|
90
|
+
];
|
|
91
|
+
function refuse(message) {
|
|
92
|
+
return { kind: 'refuse', message };
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=packageKind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageKind.js","sourceRoot":"","sources":["../../../src/utils/packageKind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAC,QAAQ,EAAC,MAAM,4BAA4B,CAAC;AAEpD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAC;AAMrE,MAAM,CAAC,MAAM,WAAW,GAAiC;IACvD,QAAQ,EAAE,MAAM;IAChB,MAAM,EAAE,SAAS;CAClB,CAAC;AAOF,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAQ,aAAmC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAChC,IAAI,EACJ,MAAM,EACN,KAAK,GAKN;IACC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC,yBAAyB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,IAAI,KAAK,MAAM,IAAI,MAAM,EAAE,CAAC;YAC9B,OAAO,MAAM,CACX,mFAAmF;gBACjF,wEAAwE,CAC3E,CAAC;QACJ,CAAC;QACD,OAAO,EAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAC,CAAC;IAC/C,CAAC;IACD,IAAI,KAAK;QAAE,OAAO,EAAC,IAAI,EAAE,KAAK,EAAC,CAAC;IAChC,OAAO,MAAM,CACX,oFAAoF;QAClF,iFAAiF,CACpF,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,aAAa,CAAC,IAAiB;IAC7C,OAAO,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,IAAkB;IAC7D,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,MAAM,EAAE,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,wCAAwC,WAAW,GAAG,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAmC;IACnE,MAAM,EAAE,CAAC,SAAS,CAAC;IACnB,QAAQ,EAAE,CAAC,SAAS,EAAE,kBAAkB,CAAC;CAC1C,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,oBAAoB;IACpB,oBAAoB;IACpB,cAAc;IACd,eAAe;IACf,mBAAmB;IACnB,gBAAgB;CACR,CAAC;AAEX,SAAS,MAAM,CAAC,OAAe;IAC7B,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAC,CAAC;AACnC,CAAC","sourcesContent":["/**\n * What `linked create-package` scaffolds, decided without touching anything.\n *\n * A linked package is one of two kinds (create-now arch-03 §Package types):\n *\n * - an **ontology package**, `<name>-ont`: exactly one ontology and nothing\n * else. Its ontology slug is `<name>` (no `-ont`), so its terms mint\n * `{root}ont/<name>/{Term}` while the package itself is `<name>-ont`.\n * - an **asset package**, `<name>-assets`: shapes, components and a backend,\n * and no ontology.\n *\n * `both` scaffolds the pair. The suffix is applied to the name given, unless\n * the name already carries it.\n */\nimport {bareName} from './createPackageLocation.js';\n\nexport const PACKAGE_KINDS = ['ontology', 'assets', 'both'] as const;\nexport type PackageKind = (typeof PACKAGE_KINDS)[number];\n\n/** The kinds a single package can be: `both` expands to these two. */\nexport type ScaffoldKind = Exclude<PackageKind, 'both'>;\n\nexport const KIND_SUFFIX: Record<ScaffoldKind, string> = {\n ontology: '-ont',\n assets: '-assets',\n};\n\nexport type KindDecision =\n | {kind: 'resolved'; packageKind: PackageKind}\n | {kind: 'ask'}\n | {kind: 'refuse'; message: string};\n\nexport function isPackageKind(value: string): value is PackageKind {\n return (PACKAGE_KINDS as readonly string[]).includes(value);\n}\n\n/**\n * `--kind` decides it. Without it a terminal is asked; anything else is\n * refused, so a scripted call never meets a prompt. `--remote` names one\n * repository, which cannot hold both packages.\n */\nexport function decidePackageKind({\n kind,\n remote,\n isTTY,\n}: {\n kind?: string;\n remote?: string;\n isTTY: boolean;\n}): KindDecision {\n if (kind !== undefined) {\n if (!isPackageKind(kind)) {\n return refuse(`--kind must be one of ${PACKAGE_KINDS.join(', ')}, not \"${kind}\".`);\n }\n if (kind === 'both' && remote) {\n return refuse(\n `--kind both creates two packages, and --remote names one repository. Create them ` +\n `separately: linked create-ont-package and linked create-asset-package.`,\n );\n }\n return {kind: 'resolved', packageKind: kind};\n }\n if (isTTY) return {kind: 'ask'};\n return refuse(\n `What kind of package? Pass --kind ontology (one ontology, no shapes: <name>-ont), ` +\n `--kind assets (shapes, components and a backend: <name>-assets) or --kind both.`,\n );\n}\n\n/** `both` → `['ontology', 'assets']`, in the order they are created. */\nexport function scaffoldKinds(kind: PackageKind): ScaffoldKind[] {\n return kind === 'both' ? ['ontology', 'assets'] : [kind];\n}\n\n/**\n * The package name a kind gives: `foo` → `foo-ont` / `foo-assets`, keeping an\n * npm scope (`@acme/foo` → `@acme/foo-ont`). A name that already ends in the\n * suffix is kept as it is, so `foo-ont` never becomes `foo-ont-ont`.\n */\nexport function packageNameFor(name: string, kind: ScaffoldKind): string {\n const suffix = KIND_SUFFIX[kind];\n return name.endsWith(suffix) ? name : `${name}${suffix}`;\n}\n\n/**\n * The ontology slug of an ontology package: the bare name without `-ont`.\n * `@acme/foo-ont` → `foo`. It is the `{ontologySlug}` in\n * `{root}ont/{ontologySlug}/{Term}` and the ontology's file name and prefix.\n */\nexport function ontologySlugFor(packageName: string): string {\n const bare = bareName(packageName);\n const suffix = KIND_SUFFIX.ontology;\n const slug = bare.endsWith(suffix) ? bare.slice(0, -suffix.length) : bare;\n if (!slug) {\n throw new Error(`Cannot derive an ontology slug from '${packageName}'`);\n }\n return slug;\n}\n\n/**\n * The template files of a kind, relative to the package root. The files every\n * package has come from `defaults/package`; an asset package is that whole\n * folder, an ontology package adds `defaults/package-ontology` on top of the\n * shared files only.\n */\nexport const PACKAGE_TEMPLATE_DIRS: Record<ScaffoldKind, string[]> = {\n assets: ['package'],\n ontology: ['package', 'package-ontology'],\n};\n\n/** The files of `defaults/package` every kind gets. The rest is asset-only. */\nexport const SHARED_TEMPLATE_FILES = [\n 'gitignore.template',\n 'npmignore.template',\n 'package.json',\n 'tsconfig.json',\n 'tsconfig-esm.json',\n 'src/package.ts',\n] as const;\n\nfunction refuse(message: string): KindDecision {\n return {kind: 'refuse', message};\n}\n"]}
|