@graftland/cli 0.4.0 → 0.4.1

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/README.md CHANGED
@@ -11,8 +11,9 @@ The `graft` command: `start`, `create`, `add` and `remove`.
11
11
  npm install @graftland/cli effect
12
12
  ```
13
13
 
14
- Create a project with `npx @graftland/cli create my-app --install`. Then run it
15
- with `npx graft start --watch`. You need Node.js 22.19 or later.
14
+ Create a project with `npm create @graftland@latest my-app`, which runs the same
15
+ `create` command. Then run it with `npm run dev`. You need Node.js 22.19 or
16
+ later.
16
17
 
17
18
  ## Documentation
18
19
 
package/README.zh-CN.md CHANGED
@@ -10,8 +10,8 @@
10
10
  npm install @graftland/cli effect
11
11
  ```
12
12
 
13
- 用 `npx @graftland/cli create my-app --install` 创建项目,然后用
14
- `npx graft start --watch` 运行它。需要 Node.js 22.19 或更高版本。
13
+ 用 `npm create @graftland@latest my-app` 创建项目,它运行的就是同一个 `create`
14
+ 命令。然后用 `npm run dev` 运行它。需要 Node.js 22.19 或更高版本。
15
15
 
16
16
  ## 文档
17
17
 
package/README.zh-TW.md CHANGED
@@ -10,8 +10,8 @@
10
10
  npm install @graftland/cli effect
11
11
  ```
12
12
 
13
- 用 `npx @graftland/cli create my-app --install` 建立專案,然後用
14
- `npx graft start --watch` 執行它。需要 Node.js 22.19 或更新版本。
13
+ 用 `npm create @graftland@latest my-app` 建立專案,它執行的是同一個 `create`
14
+ 命令。然後用 `npm run dev` 執行它。需要 Node.js 22.19 或更新版本。
15
15
 
16
16
  ## 文件
17
17
 
package/dist/Manage.d.ts CHANGED
@@ -1,15 +1,9 @@
1
1
  import { CommandConfigError } from "./Commands.js";
2
- import { Config, Effect, FileSystem, Option, Path } from "effect";
3
- import * as Create from "@graftland/create";
2
+ import { Config, Effect, FileSystem, Path } from "effect";
4
3
  import * as PackageManager from "@graftland/package-manager";
5
4
  declare namespace Manage_d_exports {
6
- export { add, addPlugin, create, remove };
5
+ export { add, addPlugin, remove };
7
6
  }
8
- export declare const create: (options: {
9
- readonly directory: string;
10
- readonly name: Option.Option<string>;
11
- readonly install: boolean;
12
- }) => Effect.Effect<void, Config.ConfigError | Create.CreateError | Create.InvalidName | Create.InvalidPackageManager | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | Path.Path>;
13
7
  export declare const add: (specs: readonly string[]) => Effect.Effect<void, Config.ConfigError | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | Path.Path>;
14
8
  export declare const remove: (names: ReadonlyArray<string>) => Effect.Effect<void, Config.ConfigError | PackageManager.Error, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | FileSystem.FileSystem | Path.Path>;
15
9
  /** Install a command plugin and explicitly enable its /cli entry. */
@@ -1 +1 @@
1
- {"version":3,"file":"Manage.d.ts","names":[],"sources":["../src/Manage.ts"],"mappings":";;;;;;;qBAqEa,SAAM;WACE;WACL,MAAA,OAAO;WACJ;MAWjB,OAAA,aAAA,OAAA,cAAA,OAAA,cAAA,OAAA,cAAA,OAAA,wBAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA;qBAEW,MAAG,6BAAA,OAAA,aAAA,OAAA,cAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA;qBAgBH,SAAM,OAAW,0BAAqB,OAAA,aAAA,OAAA,cAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA;;qBAuDtC,YAAS,cAAA,iCAAA,OAAA,aAAA,qBAAA,OAAA,cAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA"}
1
+ {"version":3,"file":"Manage.d.ts","names":[],"sources":["../src/Manage.ts"],"mappings":";;;;;;qBAoEa,MAAG,6BAAA,OAAA,aAAA,OAAA,cAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA;qBAgBH,SAAM,OAAW,0BAAqB,OAAA,aAAA,OAAA,cAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA;;qBAuDtC,YAAS,cAAA,iCAAA,OAAA,aAAA,qBAAA,OAAA,cAAA,eAAA,oDAAA,sBAAA,WAAA,aAAA,KAAA"}
package/dist/Manage.js CHANGED
@@ -1,18 +1,17 @@
1
1
  import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
2
  import { CommandConfigError } from "./Commands.js";
3
3
  import { home } from "./internal/commandConfig.js";
4
- import { Array, Config, Effect, FileSystem, Option, Path, Predicate, Record, Schema, String } from "effect";
4
+ import { Array, Config, Effect, FileSystem, Option, Path, Predicate, Record, Schema } from "effect";
5
5
  import * as Create from "@graftland/create";
6
6
  import * as PackageManager from "@graftland/package-manager";
7
7
  import { parseDocument } from "yaml";
8
8
  // src/Manage.ts
9
9
  /**
10
- * Creating projects and changing their dependencies.
10
+ * Changing a project's dependencies.
11
11
  */
12
12
  var Manage_exports = /* @__PURE__ */ __exportAll({
13
13
  add: () => add,
14
14
  addPlugin: () => addPlugin,
15
- create: () => create,
16
15
  remove: () => remove
17
16
  });
18
17
  const report = (result) => Effect.logInfo(`${result.agent}: ${result.added.length} added, ${result.updated.length} updated, ${result.removed.length} removed`).pipe(Effect.andThen(Option.match(result.snapshotCleanupFailure, {
@@ -38,17 +37,6 @@ const install = Effect.fn("Manage.install")(function* (directory, changes) {
38
37
  })).install(decoded);
39
38
  yield* report(result);
40
39
  });
41
- const create = Effect.fn("Manage.create")(function* (options) {
42
- const project = yield* Create.create({
43
- directory: options.directory,
44
- ...Option.match(options.name, {
45
- onNone: () => ({}),
46
- onSome: (name) => ({ name })
47
- })
48
- });
49
- yield* Effect.logInfo(`Created ${project.name} in ${project.directory}`);
50
- if (options.install) yield* install(project.directory, {});
51
- });
52
40
  const add = Effect.fn("Manage.add")(function* (specs) {
53
41
  const decoded = yield* decodeSpecs(specs);
54
42
  yield* install(".", Record.fromEntries(Array.map(decoded, (spec) => Predicate.isString(spec) ? [spec, "latest"] : [spec[0], spec[2]])));
@@ -99,7 +87,7 @@ const addPlugin = Effect.fn("Manage.addPlugin")(function* (name, global = false)
99
87
  const path = yield* Path.Path;
100
88
  const fs = yield* FileSystem.FileSystem;
101
89
  const directory = global ? yield* home : path.resolve(".");
102
- const packageName = String.startsWith("@")(name) || String.startsWith("graft-plugin-")(name) ? name : `@graftland/plugin-${name}`;
90
+ const packageName = Create.pluginPackage(name);
103
91
  const module = `${packageName}/cli`;
104
92
  const file = path.join(directory, "graft.yml");
105
93
  const text = yield* enabledConfig(file, module);
@@ -108,6 +96,6 @@ const addPlugin = Effect.fn("Manage.addPlugin")(function* (name, global = false)
108
96
  yield* fs.writeFileString(file, text).pipe(Effect.uninterruptible);
109
97
  yield* Effect.logInfo(`Enabled ${module} in ${file}`);
110
98
  });
111
- export { Manage_exports, add, addPlugin, create, remove };
99
+ export { Manage_exports, add, addPlugin, remove };
112
100
 
113
101
  //# sourceMappingURL=Manage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Manage.js","names":[],"sources":["../src/Manage.ts"],"sourcesContent":["/**\n * Creating projects and changing their dependencies.\n */\nimport {\n\tArray,\n\tConfig,\n\tEffect,\n\tFileSystem,\n\tOption,\n\tPath,\n\tPredicate,\n\tRecord,\n\tSchema,\n\tString,\n} from \"effect\"\n\nimport * as Create from \"@graftland/create\"\nimport * as PackageManager from \"@graftland/package-manager\"\n\nimport { parseDocument, type Document } from \"yaml\"\n\nimport { CommandConfigError } from \"./Commands\"\nimport { home } from \"./internal/commandConfig\"\n\nconst report = (result: PackageManager.InstallResult) =>\n\tEffect.logInfo(\n\t\t`${result.agent}: ${result.added.length} added, ${result.updated.length} updated, ${result.removed.length} removed`,\n\t).pipe(\n\t\tEffect.andThen(\n\t\t\tOption.match(result.snapshotCleanupFailure, {\n\t\t\t\tonNone: () => Effect.void,\n\t\t\t\tonSome: ({ cause, snapshotDirectory }) =>\n\t\t\t\t\tEffect.logWarning(\n\t\t\t\t\t\t\"Installation committed; snapshot cleanup failed. Retry removing the retained snapshot.\",\n\t\t\t\t\t\tcause,\n\t\t\t\t\t\t{ snapshotDirectory },\n\t\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t)\n\n/**\n * `name@range`, split at the last `@` so a scope's `@` stays in the name. A\n * bare name means the latest version.\n */\nconst Spec = Schema.Union([\n\tSchema.TemplateLiteralParser([\n\t\tPackageManager.PackageName,\n\t\t\"@\",\n\t\tSchema.String,\n\t]),\n\tPackageManager.PackageName,\n])\nconst decodeSpecs = Schema.decodeEffect(Schema.Array(Spec))\n\nconst install = Effect.fn(\"Manage.install\")(function* (\n\tdirectory: string,\n\tchanges: Readonly<Record<string, string | null>>,\n) {\n\tconst decoded = yield* Schema.decodeEffect(PackageManager.Changes)(changes)\n\t// Set by npm, pnpm and Yarn when they run graft, such as through `pnpm dlx`.\n\tconst userAgent = yield* Config.String(\"npm_config_user_agent\").pipe(\n\t\tConfig.withDefault(\"\"),\n\t)\n\tconst manager = yield* PackageManager.make({ directory, userAgent })\n\tconst result = yield* manager.install(decoded)\n\tyield* report(result)\n})\n\nexport const create = Effect.fn(\"Manage.create\")(function* (options: {\n\treadonly directory: string\n\treadonly name: Option.Option<string>\n\treadonly install: boolean\n}) {\n\tconst project = yield* Create.create({\n\t\tdirectory: options.directory,\n\t\t...Option.match(options.name, {\n\t\t\tonNone: () => ({}),\n\t\t\tonSome: (name) => ({ name }),\n\t\t}),\n\t})\n\tyield* Effect.logInfo(`Created ${project.name} in ${project.directory}`)\n\tif (options.install) yield* install(project.directory, {})\n})\n\nexport const add = Effect.fn(\"Manage.add\")(function* (\n\tspecs: ReadonlyArray<string>,\n) {\n\tconst decoded = yield* decodeSpecs(specs)\n\tyield* install(\n\t\t\".\",\n\t\tRecord.fromEntries(\n\t\t\tArray.map(decoded, (spec) =>\n\t\t\t\tPredicate.isString(spec)\n\t\t\t\t\t? ([spec, \"latest\"] as const)\n\t\t\t\t\t: ([spec[0], spec[2]] as const),\n\t\t\t),\n\t\t),\n\t)\n})\n\nexport const remove = (names: ReadonlyArray<string>) =>\n\tinstall(\n\t\t\".\",\n\t\tRecord.fromEntries(Array.map(names, (name) => [name, null] as const)),\n\t)\n\nconst enabledConfig = Effect.fnUntraced(function* (\n\tfile: string,\n\tmodule: string,\n) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst text = (yield* fs.exists(file))\n\t\t? yield* fs.readFileString(file)\n\t\t: \"[]\\n\"\n\tconst document = yield* Effect.try({\n\t\ttry: () => {\n\t\t\tconst document: Document = parseDocument(text)\n\t\t\tconst error = document.errors[0]\n\t\t\tif (error !== undefined) throw error\n\t\t\tif (document.toJS() === null) document.contents = document.createNode([])\n\t\t\treturn document\n\t\t},\n\t\tcatch: (cause) => CommandConfigError.make({ file, cause }),\n\t})\n\tconst entries = yield* Schema.decodeUnknownEffect(\n\t\tSchema.Array(Schema.Unknown),\n\t)(document.toJS())\n\tconst existing = Array.findFirstIndex(\n\t\tentries,\n\t\t(entry) =>\n\t\t\tPredicate.hasProperty(entry, \"name\") &&\n\t\t\tentry.name === module &&\n\t\t\tPredicate.hasProperty(entry, \"cli\") &&\n\t\t\tentry.cli === true,\n\t)\n\treturn yield* Effect.try({\n\t\ttry: () => {\n\t\t\tif (Option.isSome(existing))\n\t\t\t\tdocument.setIn([existing.value, \"disabled\"], false)\n\t\t\telse document.add({ name: module, cli: true })\n\t\t\treturn document.toString()\n\t\t},\n\t\tcatch: (cause) => CommandConfigError.make({ file, cause }),\n\t})\n})\nconst prepareHome = Effect.fnUntraced(function* (directory: string) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst path = yield* Path.Path\n\tyield* fs.makeDirectory(directory, { recursive: true })\n\tconst manifest = path.join(directory, \"package.json\")\n\tif (!(yield* fs.exists(manifest)))\n\t\tyield* fs.writeFileString(manifest, '{\"private\":true,\"type\":\"module\"}\\n')\n}, Effect.uninterruptible)\n\n/** Install a command plugin and explicitly enable its /cli entry. */\nexport const addPlugin = Effect.fn(\"Manage.addPlugin\")(function* (\n\tname: string,\n\tglobal: boolean = false,\n) {\n\tconst path = yield* Path.Path\n\tconst fs = yield* FileSystem.FileSystem\n\tconst directory = global ? yield* home : path.resolve(\".\")\n\tconst packageName =\n\t\tString.startsWith(\"@\")(name) || String.startsWith(\"graft-plugin-\")(name)\n\t\t\t? name\n\t\t\t: `@graftland/plugin-${name}`\n\tconst module = `${packageName}/cli`\n\tconst file = path.join(directory, \"graft.yml\")\n\tconst text = yield* enabledConfig(file, module)\n\tif (global) yield* prepareHome(directory)\n\tyield* install(directory, Record.singleton(packageName, \"latest\"))\n\t// Once accepted, the native write must finish before command cleanup can proceed.\n\tyield* fs.writeFileString(file, text).pipe(Effect.uninterruptible)\n\tyield* Effect.logInfo(`Enabled ${module} in ${file}`)\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"Manage.js","names":[],"sources":["../src/Manage.ts"],"sourcesContent":["/**\n * Changing a project's dependencies.\n */\nimport {\n\tArray,\n\tConfig,\n\tEffect,\n\tFileSystem,\n\tOption,\n\tPath,\n\tPredicate,\n\tRecord,\n\tSchema,\n} from \"effect\"\n\nimport * as Create from \"@graftland/create\"\nimport * as PackageManager from \"@graftland/package-manager\"\n\nimport { parseDocument, type Document } from \"yaml\"\n\nimport { CommandConfigError } from \"./Commands\"\nimport { home } from \"./internal/commandConfig\"\n\nconst report = (result: PackageManager.InstallResult) =>\n\tEffect.logInfo(\n\t\t`${result.agent}: ${result.added.length} added, ${result.updated.length} updated, ${result.removed.length} removed`,\n\t).pipe(\n\t\tEffect.andThen(\n\t\t\tOption.match(result.snapshotCleanupFailure, {\n\t\t\t\tonNone: () => Effect.void,\n\t\t\t\tonSome: ({ cause, snapshotDirectory }) =>\n\t\t\t\t\tEffect.logWarning(\n\t\t\t\t\t\t\"Installation committed; snapshot cleanup failed. Retry removing the retained snapshot.\",\n\t\t\t\t\t\tcause,\n\t\t\t\t\t\t{ snapshotDirectory },\n\t\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t)\n\n/**\n * `name@range`, split at the last `@` so a scope's `@` stays in the name. A\n * bare name means the latest version.\n */\nconst Spec = Schema.Union([\n\tSchema.TemplateLiteralParser([\n\t\tPackageManager.PackageName,\n\t\t\"@\",\n\t\tSchema.String,\n\t]),\n\tPackageManager.PackageName,\n])\nconst decodeSpecs = Schema.decodeEffect(Schema.Array(Spec))\n\nconst install = Effect.fn(\"Manage.install\")(function* (\n\tdirectory: string,\n\tchanges: Readonly<Record<string, string | null>>,\n) {\n\tconst decoded = yield* Schema.decodeEffect(PackageManager.Changes)(changes)\n\t// Set by npm, pnpm and Yarn when they run graft, such as through `pnpm dlx`.\n\tconst userAgent = yield* Config.String(\"npm_config_user_agent\").pipe(\n\t\tConfig.withDefault(\"\"),\n\t)\n\tconst manager = yield* PackageManager.make({ directory, userAgent })\n\tconst result = yield* manager.install(decoded)\n\tyield* report(result)\n})\n\nexport const add = Effect.fn(\"Manage.add\")(function* (\n\tspecs: ReadonlyArray<string>,\n) {\n\tconst decoded = yield* decodeSpecs(specs)\n\tyield* install(\n\t\t\".\",\n\t\tRecord.fromEntries(\n\t\t\tArray.map(decoded, (spec) =>\n\t\t\t\tPredicate.isString(spec)\n\t\t\t\t\t? ([spec, \"latest\"] as const)\n\t\t\t\t\t: ([spec[0], spec[2]] as const),\n\t\t\t),\n\t\t),\n\t)\n})\n\nexport const remove = (names: ReadonlyArray<string>) =>\n\tinstall(\n\t\t\".\",\n\t\tRecord.fromEntries(Array.map(names, (name) => [name, null] as const)),\n\t)\n\nconst enabledConfig = Effect.fnUntraced(function* (\n\tfile: string,\n\tmodule: string,\n) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst text = (yield* fs.exists(file))\n\t\t? yield* fs.readFileString(file)\n\t\t: \"[]\\n\"\n\tconst document = yield* Effect.try({\n\t\ttry: () => {\n\t\t\tconst document: Document = parseDocument(text)\n\t\t\tconst error = document.errors[0]\n\t\t\tif (error !== undefined) throw error\n\t\t\tif (document.toJS() === null) document.contents = document.createNode([])\n\t\t\treturn document\n\t\t},\n\t\tcatch: (cause) => CommandConfigError.make({ file, cause }),\n\t})\n\tconst entries = yield* Schema.decodeUnknownEffect(\n\t\tSchema.Array(Schema.Unknown),\n\t)(document.toJS())\n\tconst existing = Array.findFirstIndex(\n\t\tentries,\n\t\t(entry) =>\n\t\t\tPredicate.hasProperty(entry, \"name\") &&\n\t\t\tentry.name === module &&\n\t\t\tPredicate.hasProperty(entry, \"cli\") &&\n\t\t\tentry.cli === true,\n\t)\n\treturn yield* Effect.try({\n\t\ttry: () => {\n\t\t\tif (Option.isSome(existing))\n\t\t\t\tdocument.setIn([existing.value, \"disabled\"], false)\n\t\t\telse document.add({ name: module, cli: true })\n\t\t\treturn document.toString()\n\t\t},\n\t\tcatch: (cause) => CommandConfigError.make({ file, cause }),\n\t})\n})\nconst prepareHome = Effect.fnUntraced(function* (directory: string) {\n\tconst fs = yield* FileSystem.FileSystem\n\tconst path = yield* Path.Path\n\tyield* fs.makeDirectory(directory, { recursive: true })\n\tconst manifest = path.join(directory, \"package.json\")\n\tif (!(yield* fs.exists(manifest)))\n\t\tyield* fs.writeFileString(manifest, '{\"private\":true,\"type\":\"module\"}\\n')\n}, Effect.uninterruptible)\n\n/** Install a command plugin and explicitly enable its /cli entry. */\nexport const addPlugin = Effect.fn(\"Manage.addPlugin\")(function* (\n\tname: string,\n\tglobal: boolean = false,\n) {\n\tconst path = yield* Path.Path\n\tconst fs = yield* FileSystem.FileSystem\n\tconst directory = global ? yield* home : path.resolve(\".\")\n\tconst packageName = Create.pluginPackage(name)\n\tconst module = `${packageName}/cli`\n\tconst file = path.join(directory, \"graft.yml\")\n\tconst text = yield* enabledConfig(file, module)\n\tif (global) yield* prepareHome(directory)\n\tyield* install(directory, Record.singleton(packageName, \"latest\"))\n\t// Once accepted, the native write must finish before command cleanup can proceed.\n\tyield* fs.writeFileString(file, text).pipe(Effect.uninterruptible)\n\tyield* Effect.logInfo(`Enabled ${module} in ${file}`)\n})\n"],"mappings":"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"}
package/dist/bin.js CHANGED
@@ -6,6 +6,7 @@ import { Array, Effect, Layer, Logger, Option, Stdio } from "effect";
6
6
  import { NodeRuntime } from "@effect/platform-node";
7
7
  import { Graft } from "@graftland/graft";
8
8
  import { Argument, CliError, Command, Flag } from "effect/cli";
9
+ import { command } from "@graftland/create/Command";
9
10
  // src/bin.ts
10
11
  /**
11
12
  * The `graft` executable. Running this module starts the program.
@@ -18,11 +19,6 @@ const start = Command.make("start", {
18
19
  ...options,
19
20
  envFile: Option.getOrUndefined(options.envFile)
20
21
  })))).pipe(Command.withDescription("Run the application described by a config file"));
21
- const create = Command.make("create", {
22
- directory: Argument.String("directory").pipe(Argument.withDescription("Where to create the project")),
23
- name: Flag.String("name").pipe(Flag.withDescription("Package name; defaults to the directory name"), Flag.optional),
24
- install: Flag.Boolean("install").pipe(Flag.withDescription("Install dependencies afterwards"), Flag.withDefault(false))
25
- }, (options) => Effect.promise(() => import("./Manage.js")).pipe(Effect.uninterruptible, Effect.flatMap((Manage) => Manage.create(options)))).pipe(Command.withDescription("Create a new Graft project"));
26
22
  const add = Command.make("add", {
27
23
  packages: Argument.variadic(Argument.String("package")),
28
24
  plugin: Flag.String("plugin").pipe(Flag.optional),
@@ -46,7 +42,7 @@ const program = Effect.gen(function* () {
46
42
  const context = yield* Layer.build(Graft.layer);
47
43
  return yield* run([
48
44
  start,
49
- create,
45
+ command,
50
46
  add,
51
47
  remove
52
48
  ], graft, version, args).pipe(Effect.provideContext(context));
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","names":["Host.output","Host.run"],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * The `graft` executable. Running this module starts the program.\n */\nimport { Array, Effect, Layer, Logger, Option, Stdio } from \"effect\"\nimport { Argument, CliError, Command, Flag } from \"effect/cli\"\nimport { NodeRuntime } from \"@effect/platform-node\"\n\nimport { Graft } from \"@graftland/graft\"\n\nimport { version } from \"../package.json\" with { type: \"json\" }\nimport { platform } from \"./Application\"\nimport * as Host from \"./internal/commandHost\"\n\nconst start = Command.make(\n\t\"start\",\n\t{\n\t\tconfig: Argument.String(\"config\").pipe(\n\t\t\tArgument.withDescription(\"Path of the config file\"),\n\t\t\tArgument.withDefault(\"graft.yml\"),\n\t\t),\n\t\twatch: Flag.Boolean(\"watch\").pipe(\n\t\t\tFlag.withAlias(\"w\"),\n\t\t\tFlag.withDescription(\"Reload plugins and config when files change\"),\n\t\t\tFlag.withDefault(false),\n\t\t),\n\t\tenvFile: Flag.String(\"env-file\").pipe(\n\t\t\tFlag.withDescription(\n\t\t\t\t\"Read variables for !env from a .env file; the process environment takes precedence\",\n\t\t\t),\n\t\t\tFlag.optional,\n\t\t),\n\t},\n\t(options) =>\n\t\tEffect.promise(() => import(\"./Start\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t\tEffect.flatMap((Start) =>\n\t\t\t\tStart.run({\n\t\t\t\t\t...options,\n\t\t\t\t\tenvFile: Option.getOrUndefined(options.envFile),\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n).pipe(\n\tCommand.withDescription(\"Run the application described by a config file\"),\n)\n\nconst create = Command.make(\n\t\"create\",\n\t{\n\t\tdirectory: Argument.String(\"directory\").pipe(\n\t\t\tArgument.withDescription(\"Where to create the project\"),\n\t\t),\n\t\tname: Flag.String(\"name\").pipe(\n\t\t\tFlag.withDescription(\"Package name; defaults to the directory name\"),\n\t\t\tFlag.optional,\n\t\t),\n\t\tinstall: Flag.Boolean(\"install\").pipe(\n\t\t\tFlag.withDescription(\"Install dependencies afterwards\"),\n\t\t\tFlag.withDefault(false),\n\t\t),\n\t},\n\t(options) =>\n\t\tEffect.promise(() => import(\"./Manage\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t\tEffect.flatMap((Manage) => Manage.create(options)),\n\t\t),\n).pipe(Command.withDescription(\"Create a new Graft project\"))\n\nconst add = Command.make(\n\t\"add\",\n\t{\n\t\tpackages: Argument.variadic(Argument.String(\"package\")),\n\t\tplugin: Flag.String(\"plugin\").pipe(Flag.optional),\n\t\tglobal: Flag.Boolean(\"global\").pipe(Flag.withDefault(false)),\n\t},\n\tEffect.fnUntraced(function* ({ packages, plugin, global }) {\n\t\tif (\n\t\t\t(global && Option.isNone(plugin)) ||\n\t\t\t(Option.isSome(plugin) && packages.length > 0)\n\t\t)\n\t\t\treturn yield* CliError.UserError.make({\n\t\t\t\tcause: \"Conflicting install options\",\n\t\t\t\tuserMessage:\n\t\t\t\t\t\"Use add --plugin <name> [--global] without package arguments\",\n\t\t\t})\n\t\tconst Manage = yield* Effect.promise(() => import(\"./Manage\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t)\n\t\treturn yield* Option.isSome(plugin)\n\t\t\t? Manage.addPlugin(plugin.value, global)\n\t\t\t: Manage.add(packages)\n\t}),\n).pipe(\n\tCommand.withDescription(\n\t\t\"Add dependencies, restoring the project if installing fails\",\n\t),\n)\n\nconst remove = Command.make(\n\t\"remove\",\n\t{ packages: Argument.variadic(Argument.String(\"package\")) },\n\t({ packages }) =>\n\t\tEffect.promise(() => import(\"./Manage\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t\tEffect.flatMap((Manage) => Manage.remove(packages)),\n\t\t),\n).pipe(\n\tCommand.withDescription(\n\t\t\"Remove dependencies, restoring the project if installing fails\",\n\t),\n)\n\nconst graft = Command.make(\"graft\").pipe(\n\tCommand.withDescription(\"Run and manage Graft applications\"),\n\tCommand.withSharedFlags({\n\t\tstdio: Flag.Boolean(\"stdio\").pipe(Flag.withDefault(false)),\n\t\tnoPlugins: Flag.Boolean(\"no-plugins\").pipe(Flag.withDefault(false)),\n\t}),\n)\n\nconst program = Effect.gen(function* () {\n\tconst stdio = yield* Stdio.Stdio\n\tconst args = yield* stdio.args\n\treturn yield* Host.output(\n\t\tEffect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst context = yield* Layer.build(Graft.layer)\n\t\t\t\treturn yield* Host.run(\n\t\t\t\t\t[start, create, add, remove],\n\t\t\t\t\tgraft,\n\t\t\t\t\tversion,\n\t\t\t\t\targs,\n\t\t\t\t).pipe(Effect.provideContext(context))\n\t\t\t}),\n\t\t),\n\t\targs,\n\t)\n})\nNodeRuntime.runMain(\n\tEffect.scoped(\n\t\tEffect.gen(function* () {\n\t\t\tconst context = yield* Layer.build(platform)\n\t\t\treturn yield* program.pipe(Effect.provideContext(context))\n\t\t}),\n\t).pipe(\n\t\t(effect) =>\n\t\t\tEffect.withFiber((main) =>\n\t\t\t\teffect.pipe(\n\t\t\t\t\tEffect.tapCause((cause) =>\n\t\t\t\t\t\tArray.every(\n\t\t\t\t\t\t\tcause.reasons,\n\t\t\t\t\t\t\t(reason) =>\n\t\t\t\t\t\t\t\treason._tag === \"Interrupt\" && reason.fiberId === main.id,\n\t\t\t\t\t\t) ||\n\t\t\t\t\t\tArray.every(\n\t\t\t\t\t\t\tcause.reasons,\n\t\t\t\t\t\t\t(reason) =>\n\t\t\t\t\t\t\t\treason._tag === \"Fail\" && CliError.isCliError(reason.error),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t? Effect.void\n\t\t\t\t\t\t\t: Effect.logError(cause),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\tEffect.provideService(Logger.LogToStderr, true),\n\t),\n\t{ disableErrorReporting: true },\n)\n"],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","names":["Host.output","Host.run","create"],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * The `graft` executable. Running this module starts the program.\n */\nimport { Array, Effect, Layer, Logger, Option, Stdio } from \"effect\"\nimport { Argument, CliError, Command, Flag } from \"effect/cli\"\nimport { NodeRuntime } from \"@effect/platform-node\"\n\nimport { command as create } from \"@graftland/create/Command\"\nimport { Graft } from \"@graftland/graft\"\n\nimport { version } from \"../package.json\" with { type: \"json\" }\nimport { platform } from \"./Application\"\nimport * as Host from \"./internal/commandHost\"\n\nconst start = Command.make(\n\t\"start\",\n\t{\n\t\tconfig: Argument.String(\"config\").pipe(\n\t\t\tArgument.withDescription(\"Path of the config file\"),\n\t\t\tArgument.withDefault(\"graft.yml\"),\n\t\t),\n\t\twatch: Flag.Boolean(\"watch\").pipe(\n\t\t\tFlag.withAlias(\"w\"),\n\t\t\tFlag.withDescription(\"Reload plugins and config when files change\"),\n\t\t\tFlag.withDefault(false),\n\t\t),\n\t\tenvFile: Flag.String(\"env-file\").pipe(\n\t\t\tFlag.withDescription(\n\t\t\t\t\"Read variables for !env from a .env file; the process environment takes precedence\",\n\t\t\t),\n\t\t\tFlag.optional,\n\t\t),\n\t},\n\t(options) =>\n\t\tEffect.promise(() => import(\"./Start\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t\tEffect.flatMap((Start) =>\n\t\t\t\tStart.run({\n\t\t\t\t\t...options,\n\t\t\t\t\tenvFile: Option.getOrUndefined(options.envFile),\n\t\t\t\t}),\n\t\t\t),\n\t\t),\n).pipe(\n\tCommand.withDescription(\"Run the application described by a config file\"),\n)\n\nconst add = Command.make(\n\t\"add\",\n\t{\n\t\tpackages: Argument.variadic(Argument.String(\"package\")),\n\t\tplugin: Flag.String(\"plugin\").pipe(Flag.optional),\n\t\tglobal: Flag.Boolean(\"global\").pipe(Flag.withDefault(false)),\n\t},\n\tEffect.fnUntraced(function* ({ packages, plugin, global }) {\n\t\tif (\n\t\t\t(global && Option.isNone(plugin)) ||\n\t\t\t(Option.isSome(plugin) && packages.length > 0)\n\t\t)\n\t\t\treturn yield* CliError.UserError.make({\n\t\t\t\tcause: \"Conflicting install options\",\n\t\t\t\tuserMessage:\n\t\t\t\t\t\"Use add --plugin <name> [--global] without package arguments\",\n\t\t\t})\n\t\tconst Manage = yield* Effect.promise(() => import(\"./Manage\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t)\n\t\treturn yield* Option.isSome(plugin)\n\t\t\t? Manage.addPlugin(plugin.value, global)\n\t\t\t: Manage.add(packages)\n\t}),\n).pipe(\n\tCommand.withDescription(\n\t\t\"Add dependencies, restoring the project if installing fails\",\n\t),\n)\n\nconst remove = Command.make(\n\t\"remove\",\n\t{ packages: Argument.variadic(Argument.String(\"package\")) },\n\t({ packages }) =>\n\t\tEffect.promise(() => import(\"./Manage\")).pipe(\n\t\t\tEffect.uninterruptible,\n\t\t\tEffect.flatMap((Manage) => Manage.remove(packages)),\n\t\t),\n).pipe(\n\tCommand.withDescription(\n\t\t\"Remove dependencies, restoring the project if installing fails\",\n\t),\n)\n\nconst graft = Command.make(\"graft\").pipe(\n\tCommand.withDescription(\"Run and manage Graft applications\"),\n\tCommand.withSharedFlags({\n\t\tstdio: Flag.Boolean(\"stdio\").pipe(Flag.withDefault(false)),\n\t\tnoPlugins: Flag.Boolean(\"no-plugins\").pipe(Flag.withDefault(false)),\n\t}),\n)\n\nconst program = Effect.gen(function* () {\n\tconst stdio = yield* Stdio.Stdio\n\tconst args = yield* stdio.args\n\treturn yield* Host.output(\n\t\tEffect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst context = yield* Layer.build(Graft.layer)\n\t\t\t\treturn yield* Host.run(\n\t\t\t\t\t[start, create, add, remove],\n\t\t\t\t\tgraft,\n\t\t\t\t\tversion,\n\t\t\t\t\targs,\n\t\t\t\t).pipe(Effect.provideContext(context))\n\t\t\t}),\n\t\t),\n\t\targs,\n\t)\n})\nNodeRuntime.runMain(\n\tEffect.scoped(\n\t\tEffect.gen(function* () {\n\t\t\tconst context = yield* Layer.build(platform)\n\t\t\treturn yield* program.pipe(Effect.provideContext(context))\n\t\t}),\n\t).pipe(\n\t\t(effect) =>\n\t\t\tEffect.withFiber((main) =>\n\t\t\t\teffect.pipe(\n\t\t\t\t\tEffect.tapCause((cause) =>\n\t\t\t\t\t\tArray.every(\n\t\t\t\t\t\t\tcause.reasons,\n\t\t\t\t\t\t\t(reason) =>\n\t\t\t\t\t\t\t\treason._tag === \"Interrupt\" && reason.fiberId === main.id,\n\t\t\t\t\t\t) ||\n\t\t\t\t\t\tArray.every(\n\t\t\t\t\t\t\tcause.reasons,\n\t\t\t\t\t\t\t(reason) =>\n\t\t\t\t\t\t\t\treason._tag === \"Fail\" && CliError.isCliError(reason.error),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t? Effect.void\n\t\t\t\t\t\t\t: Effect.logError(cause),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\tEffect.provideService(Logger.LogToStderr, true),\n\t),\n\t{ disableErrorReporting: true },\n)\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graftland/cli",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22.19.0"
@@ -37,11 +37,11 @@
37
37
  "vitest": "5.1.0"
38
38
  },
39
39
  "dependencies": {
40
- "@graftland/graft": "0.4.0",
41
- "@graftland/loader": "0.4.0",
42
- "@graftland/hmr": "0.4.0",
43
- "@graftland/create": "0.4.0",
44
- "@graftland/package-manager": "0.4.0",
40
+ "@graftland/graft": "0.4.1",
41
+ "@graftland/loader": "0.4.1",
42
+ "@graftland/hmr": "0.4.1",
43
+ "@graftland/create": "0.4.1",
44
+ "@graftland/package-manager": "0.4.1",
45
45
  "@effect/platform-node": "4.1.2",
46
46
  "yaml": "2.9.1"
47
47
  },
package/src/Manage.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Creating projects and changing their dependencies.
2
+ * Changing a project's dependencies.
3
3
  */
4
4
  import {
5
5
  Array,
@@ -11,7 +11,6 @@ import {
11
11
  Predicate,
12
12
  Record,
13
13
  Schema,
14
- String,
15
14
  } from "effect"
16
15
 
17
16
  import * as Create from "@graftland/create"
@@ -67,22 +66,6 @@ const install = Effect.fn("Manage.install")(function* (
67
66
  yield* report(result)
68
67
  })
69
68
 
70
- export const create = Effect.fn("Manage.create")(function* (options: {
71
- readonly directory: string
72
- readonly name: Option.Option<string>
73
- readonly install: boolean
74
- }) {
75
- const project = yield* Create.create({
76
- directory: options.directory,
77
- ...Option.match(options.name, {
78
- onNone: () => ({}),
79
- onSome: (name) => ({ name }),
80
- }),
81
- })
82
- yield* Effect.logInfo(`Created ${project.name} in ${project.directory}`)
83
- if (options.install) yield* install(project.directory, {})
84
- })
85
-
86
69
  export const add = Effect.fn("Manage.add")(function* (
87
70
  specs: ReadonlyArray<string>,
88
71
  ) {
@@ -161,10 +144,7 @@ export const addPlugin = Effect.fn("Manage.addPlugin")(function* (
161
144
  const path = yield* Path.Path
162
145
  const fs = yield* FileSystem.FileSystem
163
146
  const directory = global ? yield* home : path.resolve(".")
164
- const packageName =
165
- String.startsWith("@")(name) || String.startsWith("graft-plugin-")(name)
166
- ? name
167
- : `@graftland/plugin-${name}`
147
+ const packageName = Create.pluginPackage(name)
168
148
  const module = `${packageName}/cli`
169
149
  const file = path.join(directory, "graft.yml")
170
150
  const text = yield* enabledConfig(file, module)
package/src/bin.ts CHANGED
@@ -6,6 +6,7 @@ import { Array, Effect, Layer, Logger, Option, Stdio } from "effect"
6
6
  import { Argument, CliError, Command, Flag } from "effect/cli"
7
7
  import { NodeRuntime } from "@effect/platform-node"
8
8
 
9
+ import { command as create } from "@graftland/create/Command"
9
10
  import { Graft } from "@graftland/graft"
10
11
 
11
12
  import { version } from "../package.json" with { type: "json" }
@@ -45,28 +46,6 @@ const start = Command.make(
45
46
  Command.withDescription("Run the application described by a config file"),
46
47
  )
47
48
 
48
- const create = Command.make(
49
- "create",
50
- {
51
- directory: Argument.String("directory").pipe(
52
- Argument.withDescription("Where to create the project"),
53
- ),
54
- name: Flag.String("name").pipe(
55
- Flag.withDescription("Package name; defaults to the directory name"),
56
- Flag.optional,
57
- ),
58
- install: Flag.Boolean("install").pipe(
59
- Flag.withDescription("Install dependencies afterwards"),
60
- Flag.withDefault(false),
61
- ),
62
- },
63
- (options) =>
64
- Effect.promise(() => import("./Manage")).pipe(
65
- Effect.uninterruptible,
66
- Effect.flatMap((Manage) => Manage.create(options)),
67
- ),
68
- ).pipe(Command.withDescription("Create a new Graft project"))
69
-
70
49
  const add = Command.make(
71
50
  "add",
72
51
  {