anhedral 0.1.0 → 0.1.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 +69 -11
- package/dist/branding.d.ts +2 -0
- package/dist/branding.js +9 -1
- package/dist/commands.js +1 -1
- package/dist/templates/default-web.js +798 -230
- package/dist/templates/frontend.js +1 -1
- package/dist/toolchain.js +6 -0
- package/dist/util.d.ts +1 -1
- package/dist/util.js +62 -38
- package/favicon.ico +0 -0
- package/package.json +12 -4
|
@@ -9,7 +9,7 @@ export async function scaffoldFrontend(root, { projectName, displayName }) {
|
|
|
9
9
|
// ── 1. Scaffold via react-native-reusables CLI ────────────────────────
|
|
10
10
|
console.log(' Scaffolding Expo app with react-native-reusables...');
|
|
11
11
|
fs.mkdirSync(dir, { recursive: true });
|
|
12
|
-
execExpect(`pnpm dlx ${toolPackageRef('@react-native-reusables/cli', toolchain.reactNativeReusables)} init -t clerk-auth`, dir, [
|
|
12
|
+
await execExpect(`pnpm dlx ${toolPackageRef('@react-native-reusables/cli', toolchain.reactNativeReusables)} init -t clerk-auth`, dir, [
|
|
13
13
|
['What is the name of your project?', projectName],
|
|
14
14
|
['Would you like to install dependencies?', 'n'],
|
|
15
15
|
['Would you like to initialize a Git repository?', 'n'],
|
package/dist/toolchain.js
CHANGED
|
@@ -11,11 +11,17 @@ const TOOLCHAIN_SPECS = {
|
|
|
11
11
|
},
|
|
12
12
|
stable: {
|
|
13
13
|
verifiedAt: '2026-03-22',
|
|
14
|
+
// renovate: datasource=npm depName=create-vite
|
|
14
15
|
viteCreate: '7.1.4',
|
|
16
|
+
// renovate: datasource=npm depName=shadcn
|
|
15
17
|
shadcn: '4.1.0',
|
|
18
|
+
// renovate: datasource=npm depName=@react-native-reusables/cli
|
|
16
19
|
reactNativeReusables: '0.5.0',
|
|
20
|
+
// renovate: datasource=npm depName=wxt
|
|
17
21
|
wxt: '0.20.20',
|
|
22
|
+
// renovate: datasource=npm depName=@tauri-apps/cli
|
|
18
23
|
tauriCli: '2.8.4',
|
|
24
|
+
// renovate: datasource=npm depName=@tauri-apps/api
|
|
19
25
|
tauriApi: '2.8.0',
|
|
20
26
|
},
|
|
21
27
|
};
|
package/dist/util.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export declare function appendGitignore(root: string, lines: string[]): void;
|
|
|
3
3
|
export declare function exec(cmd: string, cwd: string): void;
|
|
4
4
|
export declare function execWithInput(cmd: string, cwd: string, stdinInput: string): void;
|
|
5
5
|
export declare function liftNestedProject(root: string, nestedName: string): void;
|
|
6
|
-
export declare function execExpect(cmd: string, cwd: string, prompts: [waitFor: string, answer: string][]): void
|
|
6
|
+
export declare function execExpect(cmd: string, cwd: string, prompts: [waitFor: string, answer: string][], timeoutMs?: number): Promise<void>;
|
package/dist/util.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { execSync } from 'node:child_process';
|
|
2
|
+
import { execSync, spawn } from 'node:child_process';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
export function writeFile(filePath, content) {
|
|
5
5
|
mkdirSync(path.dirname(filePath), { recursive: true });
|
|
@@ -56,44 +56,68 @@ export function liftNestedProject(root, nestedName) {
|
|
|
56
56
|
renameSync(tempSelfNamedChild, path.join(root, nestedName));
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return
|
|
64
|
-
.replace(/\\/g, '\\\\')
|
|
65
|
-
.replace(/"/g, '\\"')
|
|
66
|
-
.replace(/\[/g, '\\[')
|
|
67
|
-
.replace(/\]/g, '\\]')
|
|
68
|
-
.replace(/\$/g, '\\$')
|
|
69
|
-
.replace(/\r/g, '\\r')
|
|
70
|
-
.replace(/\n/g, '\\n');
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Escape a string for use inside a Tcl double-quoted `send` argument.
|
|
74
|
-
* Converts JS escape sequences to their Tcl equivalents.
|
|
75
|
-
*/
|
|
76
|
-
function tclSendEscape(s) {
|
|
77
|
-
return tclDoubleQuoteEscape(s).replace(/\x1b/g, '\\033');
|
|
59
|
+
function trimOutputTail(output, maxLength = 4000) {
|
|
60
|
+
if (output.length <= maxLength) {
|
|
61
|
+
return output;
|
|
62
|
+
}
|
|
63
|
+
return output.slice(output.length - maxLength);
|
|
78
64
|
}
|
|
79
|
-
export function execExpect(cmd, cwd, prompts) {
|
|
65
|
+
export async function execExpect(cmd, cwd, prompts, timeoutMs = 120_000) {
|
|
80
66
|
console.log(` $ ${cmd}`);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
67
|
+
await new Promise((resolve, reject) => {
|
|
68
|
+
const child = spawn('bash', ['-lc', cmd], {
|
|
69
|
+
cwd,
|
|
70
|
+
env: process.env,
|
|
71
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
72
|
+
});
|
|
73
|
+
let combinedOutput = '';
|
|
74
|
+
let promptIndex = 0;
|
|
75
|
+
let settled = false;
|
|
76
|
+
const finish = (handler) => {
|
|
77
|
+
if (settled) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
settled = true;
|
|
81
|
+
clearTimeout(timeoutId);
|
|
82
|
+
handler();
|
|
83
|
+
};
|
|
84
|
+
const maybeAnswerPrompt = () => {
|
|
85
|
+
while (promptIndex < prompts.length && combinedOutput.includes(prompts[promptIndex][0])) {
|
|
86
|
+
child.stdin.write(`${prompts[promptIndex][1]}\n`);
|
|
87
|
+
promptIndex += 1;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const handleChunk = (chunk, target) => {
|
|
91
|
+
const text = chunk.toString();
|
|
92
|
+
combinedOutput += text;
|
|
93
|
+
target.write(text);
|
|
94
|
+
maybeAnswerPrompt();
|
|
95
|
+
};
|
|
96
|
+
const timeoutId = setTimeout(() => {
|
|
97
|
+
child.kill('SIGTERM');
|
|
98
|
+
finish(() => {
|
|
99
|
+
reject(new Error(`Command timed out after ${timeoutMs}ms: ${cmd}\n` +
|
|
100
|
+
`Answered ${promptIndex}/${prompts.length} prompts.\n` +
|
|
101
|
+
`Recent output:\n${trimOutputTail(combinedOutput)}`));
|
|
102
|
+
});
|
|
103
|
+
}, timeoutMs);
|
|
104
|
+
child.stdout.on('data', (chunk) => handleChunk(chunk, process.stdout));
|
|
105
|
+
child.stderr.on('data', (chunk) => handleChunk(chunk, process.stderr));
|
|
106
|
+
child.on('error', (error) => {
|
|
107
|
+
finish(() => {
|
|
108
|
+
reject(error);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
child.on('close', (code) => {
|
|
112
|
+
finish(() => {
|
|
113
|
+
if (code === 0) {
|
|
114
|
+
resolve();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
reject(new Error(`Command failed with exit code ${code}: ${cmd}\n` +
|
|
118
|
+
`Answered ${promptIndex}/${prompts.length} prompts.\n` +
|
|
119
|
+
`Recent output:\n${trimOutputTail(combinedOutput)}`));
|
|
120
|
+
});
|
|
121
|
+
});
|
|
98
122
|
});
|
|
99
123
|
}
|
package/favicon.ico
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anhedral",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Opinionated init CLI for Next, Next + Fastify, Expo + Fastify, and backend starters with Neon, Drizzle, R2, auth, and billing integrations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"anhedral": "
|
|
7
|
+
"anhedral": "bin/anhedral.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin",
|
|
11
11
|
"dist",
|
|
12
12
|
"LICENSE",
|
|
13
13
|
"README.md",
|
|
14
|
-
"anhedral.svg"
|
|
14
|
+
"anhedral.svg",
|
|
15
|
+
"favicon.ico"
|
|
15
16
|
],
|
|
16
17
|
"repository": {
|
|
17
18
|
"type": "git",
|
|
@@ -21,6 +22,10 @@
|
|
|
21
22
|
"bugs": {
|
|
22
23
|
"url": "https://github.com/anhedral/anhedral-init/issues"
|
|
23
24
|
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"provenance": true
|
|
28
|
+
},
|
|
24
29
|
"engines": {
|
|
25
30
|
"node": ">=20.0.0"
|
|
26
31
|
},
|
|
@@ -36,7 +41,10 @@
|
|
|
36
41
|
"test:cli:validation": "node scripts/test-cli-validation.js",
|
|
37
42
|
"test:cli:scaffold": "node scripts/test-cli-scaffold-headless.js",
|
|
38
43
|
"test:e2e": "node scripts/test-e2e-public-stacks.js",
|
|
39
|
-
"test:
|
|
44
|
+
"test:e2e:latest": "node scripts/test-e2e-public-stacks.js --toolchain latest",
|
|
45
|
+
"test:all": "pnpm test && pnpm test:e2e",
|
|
46
|
+
"release:check": "pnpm test:all && npm pack --dry-run",
|
|
47
|
+
"demo:refresh": "pnpm build && node scripts/refresh-demo.js"
|
|
40
48
|
},
|
|
41
49
|
"keywords": [
|
|
42
50
|
"cli",
|