create-loutre 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,11 +8,10 @@ Loutre Applicationをstarterから作成するproject initializerです。Runtim
8
8
  npm create loutre@latest my-app
9
9
  ```
10
10
 
11
- BunやDenoからも実行できます。
11
+ Bunからも実行できます。
12
12
 
13
13
  ```sh
14
14
  bun create loutre my-app
15
- deno x -A npm:create-loutre@latest my-app
16
15
  ```
17
16
 
18
17
  対話形式でtargetとpackage managerを選択できます。
@@ -21,7 +20,6 @@ deno x -A npm:create-loutre@latest my-app
21
20
 
22
21
  - Node.js
23
22
  - Bun
24
- - Deno
25
23
  - Cloudflare Workers
26
24
  - AWS Lambda
27
25
 
@@ -31,7 +29,6 @@ deno x -A npm:create-loutre@latest my-app
31
29
  - pnpm
32
30
  - Yarn
33
31
  - Bun
34
- - Deno
35
32
 
36
33
  ## Non-interactive usage
37
34
 
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { relative } from 'node:path';
3
- import { isCancel, select, text } from '@clack/prompts';
3
+ import { select, text } from '@clack/prompts';
4
4
  import { Command, CommanderError, Option } from 'commander';
5
5
  import { bootstrapApplication } from '@loutrejs/loutre';
6
6
  import { detectPresentationTerminal, renderLoutreBrand, } from '@loutrejs/loutre/presentation';
@@ -152,11 +152,11 @@ function createProcessIO() {
152
152
  }
153
153
  async function terminalPrompt(message, initialValue) {
154
154
  const result = await text({ message, defaultValue: initialValue });
155
- return isCancel(result) ? undefined : result;
155
+ return typeof result === 'string' ? result : undefined;
156
156
  }
157
157
  async function terminalSelect(message, options, initialValue) {
158
158
  const result = await select({ message, options: [...options], initialValue });
159
- return isCancel(result) ? undefined : result;
159
+ return typeof result === 'string' ? result : undefined;
160
160
  }
161
161
  function installDependencies(directory, packageManager) {
162
162
  const command = executableFor(packageManager);
@@ -184,8 +184,6 @@ function detectPackageManager(userAgent, runtime) {
184
184
  const globals = runtime;
185
185
  if (globals.Bun !== undefined)
186
186
  return 'bun';
187
- if (globals.Deno !== undefined)
188
- return 'deno';
189
187
  const name = userAgent?.split('/')[0];
190
188
  return (packageManagers.find((packageManager) => packageManager === name) ?? 'npm');
191
189
  }
@@ -203,8 +201,8 @@ function helpText() {
203
201
  'Usage: create-loutre [directory] [options]',
204
202
  '',
205
203
  'Options:',
206
- ' --target <target> node | bun | deno | cloudflare-workers | aws-lambda',
207
- ' --package-manager <package-manager> npm | pnpm | yarn | bun | deno',
204
+ ' --target <target> node | bun | cloudflare-workers | aws-lambda',
205
+ ' --package-manager <package-manager> npm | pnpm | yarn | bun',
208
206
  ' -y, --yes Use defaults for unspecified options',
209
207
  ' --no-install Skip dependency installation',
210
208
  ' -h, --help Show help',
package/dist/options.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { RuntimeEngine } from '@loutrejs/loutre/runtime';
2
- export declare const projectTargets: readonly ["node", "bun", "deno", "cloudflare-workers", "aws-lambda"];
2
+ export declare const projectTargets: readonly ["node", "bun", "cloudflare-workers", "aws-lambda"];
3
3
  export type ProjectTarget = Exclude<RuntimeEngine, 'electron' | 'unknown'>;
4
4
  export declare function createIsTarget(target: ProjectTarget): (candidate: ProjectTarget) => boolean;
5
- export declare const packageManagers: readonly ['npm', 'pnpm', 'yarn', 'bun', 'deno'];
5
+ export declare const packageManagers: readonly ['npm', 'pnpm', 'yarn', 'bun'];
6
6
  export type PackageManager = (typeof packageManagers)[number];
7
7
  export declare const targetLabels: Readonly<Record<ProjectTarget, string>>;
8
8
  export declare const packageManagerLabels: Readonly<Record<PackageManager, string>>;
package/dist/options.js CHANGED
@@ -1,18 +1,17 @@
1
+ import { match } from 'ts-pattern';
1
2
  export const projectTargets = [
2
3
  'node',
3
4
  'bun',
4
- 'deno',
5
5
  'cloudflare-workers',
6
6
  'aws-lambda',
7
7
  ];
8
8
  export function createIsTarget(target) {
9
9
  return (candidate) => target === candidate;
10
10
  }
11
- export const packageManagers = ['npm', 'pnpm', 'yarn', 'bun', 'deno'];
11
+ export const packageManagers = ['npm', 'pnpm', 'yarn', 'bun'];
12
12
  export const targetLabels = {
13
13
  node: 'Node.js',
14
14
  bun: 'Bun',
15
- deno: 'Deno',
16
15
  'cloudflare-workers': 'Cloudflare Workers',
17
16
  'aws-lambda': 'AWS Lambda',
18
17
  };
@@ -21,22 +20,15 @@ export const packageManagerLabels = {
21
20
  pnpm: 'pnpm',
22
21
  yarn: 'Yarn',
23
22
  bun: 'Bun',
24
- deno: 'Deno',
25
23
  };
26
24
  export function installCommand(packageManager) {
27
25
  return `${packageManager} install`;
28
26
  }
29
27
  export function runScriptCommand(packageManager, script) {
30
- switch (packageManager) {
31
- case 'npm':
32
- return `npm run ${script}`;
33
- case 'pnpm':
34
- return `pnpm run ${script}`;
35
- case 'yarn':
36
- return `yarn run ${script}`;
37
- case 'bun':
38
- return `bun run ${script}`;
39
- case 'deno':
40
- return `deno task ${script}`;
41
- }
28
+ return match(packageManager)
29
+ .with('npm', () => `npm run ${script}`)
30
+ .with('pnpm', () => `pnpm run ${script}`)
31
+ .with('yarn', () => `yarn run ${script}`)
32
+ .with('bun', () => `bun run ${script}`)
33
+ .exhaustive();
42
34
  }
package/dist/starter.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { readFileSync } from 'node:fs';
2
- import { cp, readFile, readdir, rename, writeFile } from 'node:fs/promises';
2
+ import { cp, readFile, rename, writeFile } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
+ import { match } from 'ts-pattern';
5
6
  import { createIsTarget, runScriptCommand, targetLabels, } from './options.js';
6
7
  const packageManifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
7
8
  const loutreVersion = requiredDependencyVersion('@loutrejs/loutre');
@@ -35,9 +36,6 @@ export async function writeStarter(targetDirectory, options) {
35
36
  verifyCommand: runScriptCommand(options.packageManager, 'verify'),
36
37
  deploymentSection: deploymentSection(options),
37
38
  });
38
- if (isTarget('deno')) {
39
- await rewriteLocalImportExtensionsForDeno(join(targetDirectory, 'src'));
40
- }
41
39
  if (isTarget('cloudflare-workers')) {
42
40
  await renderTextTemplate(join(targetDirectory, 'wrangler.jsonc'), {
43
41
  packageName: workerNameFor(options.packageName),
@@ -46,58 +44,45 @@ export async function writeStarter(targetDirectory, options) {
46
44
  }
47
45
  }
48
46
  function targetManifest(target) {
49
- switch (target) {
50
- case 'node':
51
- return {
52
- scripts: {
53
- dev: 'tsx watch src/main.ts',
54
- build: 'tsc -p tsconfig.build.json',
55
- start: 'node dist/main.js',
56
- },
57
- dependencies: { '@loutrejs/node': loutreVersion },
58
- devDependencies: { '@types/node': '^22.20.1', tsx: '^4.23.12' },
59
- engines: { node: '>=22' },
60
- types: ['node'],
61
- };
62
- case 'bun':
63
- return {
64
- scripts: {
65
- dev: 'bun --watch src/main.ts',
66
- build: 'bun build src/main.ts --outdir dist --target bun',
67
- start: 'bun dist/main.js',
68
- },
69
- devDependencies: { '@types/bun': '^1.4.0' },
70
- types: ['bun'],
71
- };
72
- case 'deno':
73
- return {
74
- scripts: {
75
- dev: 'deno run -A --watch src/main.ts',
76
- start: 'deno run -A src/main.ts',
77
- },
78
- typecheck: 'tsc --noEmit --allowImportingTsExtensions',
79
- types: [],
80
- };
81
- case 'cloudflare-workers':
82
- return {
83
- scripts: {
84
- dev: 'wrangler dev',
85
- build: 'wrangler deploy --dry-run --outdir dist',
86
- deploy: 'wrangler deploy',
87
- },
88
- devDependencies: { wrangler: '^4.127.1' },
89
- types: [],
90
- };
91
- case 'aws-lambda':
92
- return {
93
- scripts: {
94
- build: 'esbuild src/main.ts --bundle --platform=node --target=node22 --format=esm --outfile=dist/index.mjs',
95
- },
96
- devDependencies: { '@types/node': '^22.20.1', esbuild: '^0.28.2' },
97
- engines: { node: '>=22' },
98
- types: ['node'],
99
- };
100
- }
47
+ return match(target)
48
+ .with('node', () => ({
49
+ scripts: {
50
+ dev: 'tsx watch src/main.ts',
51
+ build: 'tsc -p tsconfig.build.json',
52
+ start: 'node dist/main.js',
53
+ },
54
+ dependencies: { '@loutrejs/node': loutreVersion },
55
+ devDependencies: { '@types/node': '^22.20.1', tsx: '^4.23.12' },
56
+ engines: { node: '>=22' },
57
+ types: ['node'],
58
+ }))
59
+ .with('bun', () => ({
60
+ scripts: {
61
+ dev: 'bun --watch src/main.ts',
62
+ build: 'bun build src/main.ts --outdir dist --target bun',
63
+ start: 'bun dist/main.js',
64
+ },
65
+ devDependencies: { '@types/bun': '^1.4.0' },
66
+ types: ['bun'],
67
+ }))
68
+ .with('cloudflare-workers', () => ({
69
+ scripts: {
70
+ dev: 'wrangler dev',
71
+ build: 'wrangler deploy --dry-run --outdir dist',
72
+ deploy: 'wrangler deploy',
73
+ },
74
+ devDependencies: { wrangler: '^4.127.1' },
75
+ types: [],
76
+ }))
77
+ .with('aws-lambda', () => ({
78
+ scripts: {
79
+ build: 'esbuild src/main.ts --bundle --platform=node --target=node22 --format=esm --outfile=dist/index.mjs',
80
+ },
81
+ devDependencies: { '@types/node': '^22.20.1', esbuild: '^0.28.2' },
82
+ engines: { node: '>=22' },
83
+ types: ['node'],
84
+ }))
85
+ .exhaustive();
101
86
  }
102
87
  function renderPackageJson(options) {
103
88
  const target = targetManifest(options.target);
@@ -188,9 +173,7 @@ function deploymentSection(options) {
188
173
  '## Production',
189
174
  '',
190
175
  '```sh',
191
- ...(isTarget('deno')
192
- ? []
193
- : [runScriptCommand(options.packageManager, 'build')]),
176
+ runScriptCommand(options.packageManager, 'build'),
194
177
  runScriptCommand(options.packageManager, 'start'),
195
178
  '```',
196
179
  ].join('\n');
@@ -206,20 +189,6 @@ async function replaceText(path, search, replacement) {
206
189
  const content = await readFile(path, 'utf8');
207
190
  await writeFile(path, content.replaceAll(search, replacement), 'utf8');
208
191
  }
209
- async function rewriteLocalImportExtensionsForDeno(directory) {
210
- const entries = await readdir(directory, { withFileTypes: true });
211
- await Promise.all(entries.map(async (entry) => {
212
- const path = join(directory, entry.name);
213
- if (entry.isDirectory()) {
214
- await rewriteLocalImportExtensionsForDeno(path);
215
- return;
216
- }
217
- if (!entry.isFile() || !entry.name.endsWith('.ts'))
218
- return;
219
- const content = await readFile(path, 'utf8');
220
- await writeFile(path, content.replaceAll(/(from\s+['"]\.{1,2}\/[^'"]+)\.js(['"])/gu, '$1.ts$2'), 'utf8');
221
- }));
222
- }
223
192
  function workerNameFor(packageName) {
224
193
  return (packageName
225
194
  .replace(/[^a-z0-9-]+/gu, '-')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-loutre",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Loutre project initializer",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,9 +17,10 @@
17
17
  "provenance": true
18
18
  },
19
19
  "dependencies": {
20
- "@clack/prompts": "^1.7.0",
21
- "@loutrejs/loutre": "^0.6.0",
22
- "commander": "^15.0.0"
20
+ "@clack/prompts": "^1.8.1",
21
+ "@loutrejs/loutre": "^0.8.0",
22
+ "commander": "^15.0.0",
23
+ "ts-pattern": "^5.9.0"
23
24
  },
24
25
  "repository": {
25
26
  "type": "git",
@@ -2,3 +2,4 @@ node_modules/
2
2
  dist/
3
3
  coverage/
4
4
  .env
5
+ .loutre/
@@ -1,5 +0,0 @@
1
- import { denoRuntime } from '@loutrejs/loutre/runtime/deno'
2
- import application from './app.ts'
3
-
4
- const app = await denoRuntime.create({ application })
5
- await app.serve()