anhedral 0.8.6 → 0.9.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 +141 -38
- package/assets/anhedral-cli-init-technical.svg +15 -15
- package/assets/anhedral-cli-init.svg +16 -16
- package/dist/access.d.ts +10 -0
- package/dist/access.js +93 -0
- package/dist/auth-schema-snapshot.d.ts +346 -0
- package/dist/auth-schema-snapshot.js +347 -0
- package/dist/auth-schema.d.ts +1 -0
- package/dist/auth-schema.js +57 -0
- package/dist/bin.js +345 -39
- package/dist/bounded-file.d.ts +2 -0
- package/dist/bounded-file.js +30 -0
- package/dist/capabilities.d.ts +24 -42
- package/dist/capabilities.js +73 -75
- package/dist/cloudflare.d.ts +14 -0
- package/dist/cloudflare.js +66 -0
- package/dist/command.js +12 -3
- package/dist/delivery.d.ts +118 -0
- package/dist/delivery.js +611 -0
- package/dist/dependencies.d.ts +24 -3
- package/dist/dependencies.js +112 -74
- package/dist/dependency-order.d.ts +2 -0
- package/dist/dependency-order.js +24 -0
- package/dist/index.d.ts +18 -3
- package/dist/index.js +12 -2
- package/dist/managed-hosting.d.ts +49 -0
- package/dist/managed-hosting.js +373 -0
- package/dist/management.d.ts +3 -0
- package/dist/management.js +47 -0
- package/dist/platforms/desktop.d.ts +2 -2
- package/dist/platforms/desktop.js +25 -15
- package/dist/platforms/extension.d.ts +2 -2
- package/dist/platforms/extension.js +104 -66
- package/dist/platforms/mobile.d.ts +2 -2
- package/dist/platforms/mobile.js +13 -7
- package/dist/pnpm-policy.d.ts +0 -2
- package/dist/pnpm-policy.js +18 -13
- package/dist/project-state.d.ts +28 -0
- package/dist/project-state.js +226 -0
- package/dist/provider-readiness.d.ts +30 -0
- package/dist/provider-readiness.js +87 -0
- package/dist/provision.d.ts +46 -0
- package/dist/provision.js +197 -0
- package/dist/readiness.d.ts +4 -2
- package/dist/readiness.js +81 -14
- package/dist/registry/add.d.ts +22 -0
- package/dist/registry/add.js +198 -0
- package/dist/registry/bootstrap.d.ts +2 -0
- package/dist/registry/bootstrap.js +14 -0
- package/dist/registry/commands.d.ts +2 -0
- package/dist/registry/commands.js +99 -0
- package/dist/registry/context.d.ts +3 -0
- package/dist/registry/context.js +21 -0
- package/dist/registry/options.d.ts +2 -0
- package/dist/registry/options.js +65 -0
- package/dist/registry/receipt.d.ts +3 -0
- package/dist/registry/receipt.js +73 -0
- package/dist/registry/remote.d.ts +25 -0
- package/dist/registry/remote.js +168 -0
- package/dist/registry/resolve.d.ts +10 -0
- package/dist/registry/resolve.js +98 -0
- package/dist/registry/types.d.ts +64 -0
- package/dist/registry/usage.d.ts +1 -0
- package/dist/registry/usage.js +38 -0
- package/dist/render.d.ts +0 -4
- package/dist/render.js +3 -16
- package/dist/repository.d.ts +24 -0
- package/dist/repository.js +96 -0
- package/dist/scaffold/api.d.ts +2 -0
- package/dist/scaffold/api.js +13 -0
- package/dist/scaffold/auth.d.ts +3 -0
- package/dist/scaffold/auth.js +95 -0
- package/dist/scaffold/bootstrap.d.ts +2 -0
- package/dist/scaffold/bootstrap.js +34 -0
- package/dist/scaffold/compose.d.ts +4 -0
- package/dist/scaffold/compose.js +34 -0
- package/dist/scaffold/database.d.ts +2 -0
- package/dist/scaffold/database.js +43 -0
- package/dist/scaffold/documentation.d.ts +3 -0
- package/dist/scaffold/documentation.js +91 -0
- package/dist/scaffold/environment.d.ts +2 -0
- package/dist/scaffold/environment.js +5 -0
- package/dist/scaffold/files.d.ts +25 -0
- package/dist/scaffold/files.js +108 -0
- package/dist/scaffold/integrations.d.ts +3 -0
- package/dist/scaffold/integrations.js +7 -0
- package/dist/scaffold/services.d.ts +5 -0
- package/dist/scaffold/services.js +84 -0
- package/dist/scaffold/web.d.ts +2 -0
- package/dist/scaffold/web.js +102 -0
- package/dist/scaffold/workspace.d.ts +3 -0
- package/dist/scaffold/workspace.js +150 -0
- package/dist/security-backports.js +7 -2
- package/dist/stack-registry.d.ts +80 -0
- package/dist/stack-registry.js +424 -0
- package/dist/standard.d.ts +6 -19
- package/dist/standard.js +46 -653
- package/dist/transaction.js +47 -56
- package/dist/util.js +12 -2
- package/dist/vercel.d.ts +98 -0
- package/dist/vercel.js +796 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/vinext.d.ts +1 -0
- package/dist/vinext.js +83 -0
- package/dist/workspace-graph.d.ts +7 -0
- package/dist/workspace-graph.js +73 -0
- package/docs/application-stack-standard.md +76 -91
- package/docs/delivery-workflow.md +83 -0
- package/docs/managed-hosting-architecture.md +87 -0
- package/docs/sponsorships.md +25 -0
- package/package.json +23 -29
- package/dist/evidence-validation.d.ts +0 -2
- package/dist/evidence-validation.js +0 -18
- package/dist/foundation.d.ts +0 -6
- package/dist/foundation.js +0 -49
- package/dist/progress-view.d.ts +0 -57
- package/dist/progress-view.js +0 -69
- package/dist/progress.d.ts +0 -95
- package/dist/progress.js +0 -327
- package/dist/project.d.ts +0 -5
- package/dist/standard-products.d.ts +0 -2
- package/dist/standard-products.js +0 -6
- /package/assets/{images/svg/logo-white-subtract.svg → anhedral-mark.svg} +0 -0
- /package/dist/{project.js → registry/types.js} +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { STACK_DEPENDENCIES } from '../dependencies.js';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, rmSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { configureVinext } from '../vinext.js';
|
|
5
|
+
import { json, put, readJson, patchPackage, workerConfig } from './files.js';
|
|
6
|
+
function cleanWorkspaceManifest(root, directory) {
|
|
7
|
+
const manifestPath = `${directory}/package.json`;
|
|
8
|
+
if (!existsSync(path.join(root, manifestPath)))
|
|
9
|
+
return;
|
|
10
|
+
const manifest = readJson(root, manifestPath);
|
|
11
|
+
const sources = [];
|
|
12
|
+
const collect = (folder) => {
|
|
13
|
+
for (const entry of readdirSync(folder, { withFileTypes: true })) {
|
|
14
|
+
if (['node_modules', '.next', '.open-next', '.git'].includes(entry.name))
|
|
15
|
+
continue;
|
|
16
|
+
const file = path.join(folder, entry.name);
|
|
17
|
+
if (entry.isDirectory())
|
|
18
|
+
collect(file);
|
|
19
|
+
else if (/\.(tsx?|m?js|css)$/.test(entry.name))
|
|
20
|
+
sources.push(readFileSync(file, 'utf8'));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
collect(path.join(root, directory));
|
|
24
|
+
for (const name of ['lucide-react', 'zod', 'next-themes']) {
|
|
25
|
+
if (!sources.some((source) => source.includes(`"${name}`) || source.includes(`'${name}`)))
|
|
26
|
+
delete manifest.dependencies?.[name];
|
|
27
|
+
}
|
|
28
|
+
if (directory === 'packages/ui') {
|
|
29
|
+
if (!sources.some((source) => source.includes('@turbo/gen')) &&
|
|
30
|
+
!Object.values(manifest.scripts ?? {}).some((script) => String(script).includes('turbo gen')))
|
|
31
|
+
delete manifest.devDependencies?.['@turbo/gen'];
|
|
32
|
+
manifest.devDependencies = {
|
|
33
|
+
...manifest.devDependencies,
|
|
34
|
+
'postcss-load-config': STACK_DEPENDENCIES['postcss-load-config'],
|
|
35
|
+
};
|
|
36
|
+
if (manifest.dependencies?.shadcn) {
|
|
37
|
+
manifest.devDependencies.shadcn = manifest.dependencies.shadcn;
|
|
38
|
+
delete manifest.dependencies.shadcn;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
json(root, manifestPath, manifest);
|
|
42
|
+
}
|
|
43
|
+
function cleanShadcnStarter(root) {
|
|
44
|
+
for (const directory of ['apps/web', 'packages/ui'])
|
|
45
|
+
cleanWorkspaceManifest(root, directory);
|
|
46
|
+
const themePath = 'apps/web/components/theme-provider.tsx';
|
|
47
|
+
if (existsSync(path.join(root, themePath))) {
|
|
48
|
+
const source = readFileSync(path.join(root, themePath), 'utf8');
|
|
49
|
+
// Preserve the upstream keyboard behavior while reducing branching in its guards.
|
|
50
|
+
put(root, themePath, source
|
|
51
|
+
.replace(/target.tagName === "INPUT" \|\|\s*target.tagName === "TEXTAREA" \|\|\s*target.tagName === "SELECT"/, '["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName)')
|
|
52
|
+
.replace(/if \(event.defaultPrevented \|\| event.repeat\) \{\s*return\s*\}\s*if \(event.metaKey \|\| event.ctrlKey \|\| event.altKey\) \{\s*return\s*\}\s*if \(event.key.toLowerCase\(\) !== "d"\) \{\s*return\s*\}\s*if \(isTypingTarget\(event.target\)\) \{\s*return\s*\}/, 'if ([event.defaultPrevented, event.repeat, event.metaKey, event.ctrlKey, event.altKey, event.key.toLowerCase() !== "d", isTypingTarget(event.target)].some(Boolean)) { return }'));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function scaffoldWeb({ root, options, bindings, runtimeApp, has }) {
|
|
56
|
+
cleanShadcnStarter(root);
|
|
57
|
+
put(root, 'apps/web/eslint.config.js', 'import { nextJsConfig } from "@workspace/eslint-config/next-js";\nexport default [...nextJsConfig, { ignores: [".open-next/**", ".wrangler/**", "cloudflare-env.d.ts"] }];\n');
|
|
58
|
+
patchPackage(root, 'apps/web/package.json', {
|
|
59
|
+
scripts: { typecheck: 'tsc --noEmit', lint: 'eslint . --max-warnings 0' },
|
|
60
|
+
});
|
|
61
|
+
if (has('vinext')) {
|
|
62
|
+
configureVinext(root, `${options.name}-web`, runtimeApp === 'web' ? bindings : {});
|
|
63
|
+
}
|
|
64
|
+
else if (options.hosting === 'cloudflare') {
|
|
65
|
+
patchPackage(root, 'apps/web/package.json', {
|
|
66
|
+
dependencies: {
|
|
67
|
+
'@opennextjs/cloudflare': STACK_DEPENDENCIES['@opennextjs/cloudflare'],
|
|
68
|
+
next: '16.3.8',
|
|
69
|
+
},
|
|
70
|
+
devDependencies: { wrangler: STACK_DEPENDENCIES['wrangler'] },
|
|
71
|
+
scripts: {
|
|
72
|
+
preview: 'opennextjs-cloudflare build && opennextjs-cloudflare preview',
|
|
73
|
+
deploy: 'opennextjs-cloudflare build && opennextjs-cloudflare deploy',
|
|
74
|
+
'build:worker': 'opennextjs-cloudflare build',
|
|
75
|
+
'cf:typegen': 'wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
json(root, 'apps/web/wrangler.jsonc', {
|
|
79
|
+
...workerConfig(`${options.name}-web`),
|
|
80
|
+
compatibility_flags: ['nodejs_compat', 'global_fetch_strictly_public'],
|
|
81
|
+
main: '.open-next/worker.js',
|
|
82
|
+
assets: { directory: '.open-next/assets', binding: 'ASSETS' },
|
|
83
|
+
services: [{ binding: 'WORKER_SELF_REFERENCE', service: `${options.name}-web` }],
|
|
84
|
+
...(runtimeApp === 'web' ? bindings : {}),
|
|
85
|
+
});
|
|
86
|
+
const nextConfig = ['next.config.ts', 'next.config.mjs', 'next.config.js'].find((file) => existsSync(path.join(root, 'apps/web', file)));
|
|
87
|
+
if (nextConfig) {
|
|
88
|
+
const source = readFileSync(path.join(root, 'apps/web', nextConfig), 'utf8');
|
|
89
|
+
put(root, `apps/web/${nextConfig}`, `import { initOpenNextCloudflareForDev } from '@opennextjs/cloudflare';\n${source}\ninitOpenNextCloudflareForDev();\n`);
|
|
90
|
+
}
|
|
91
|
+
put(root, 'apps/web/open-next.config.ts', 'import { defineCloudflareConfig } from "@opennextjs/cloudflare";\nexport default defineCloudflareConfig();\n');
|
|
92
|
+
put(root, 'apps/web/public/_headers', '/_next/static/*\n Cache-Control: public,max-age=31536000,immutable\n');
|
|
93
|
+
put(root, 'apps/web/.dev.vars.example', 'NEXTJS_ENV=development\n');
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
patchPackage(root, 'apps/web/package.json', { dependencies: { next: '16.4.0' } });
|
|
97
|
+
put(root, 'apps/web/next.config.ts', 'import type { NextConfig } from "next";\nconst config: NextConfig = { transpilePackages: ["@workspace/ui"], cacheComponents: true, partialPrefetching: true };\nexport default config;\n');
|
|
98
|
+
for (const file of ['next.config.js', 'next.config.mjs'])
|
|
99
|
+
rmSync(path.join(root, 'apps/web', file), { force: true });
|
|
100
|
+
json(root, 'apps/web/vercel.json', { framework: 'nextjs' });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { STACK_DEPENDENCIES } from '../dependencies.js';
|
|
2
|
+
import { setPnpmPolicy } from '../pnpm-policy.js';
|
|
3
|
+
import { writeSecurityBackports } from '../security-backports.js';
|
|
4
|
+
import { BOOTSTRAP_COMMAND } from '../registry/bootstrap.js';
|
|
5
|
+
import { appendGitignore } from '../util.js';
|
|
6
|
+
import { PACKAGE_MANAGER } from '../dependencies.js';
|
|
7
|
+
import { createSetupPlan } from '../capabilities.js';
|
|
8
|
+
import { json, put, readJson, patchPackage, } from './files.js';
|
|
9
|
+
import { writeSetupDocumentation, workerBuildSuffix } from './documentation.js';
|
|
10
|
+
import { writeEnvironmentExample } from './environment.js';
|
|
11
|
+
export function writeStandardRoot(root, options, registry, updating = false) {
|
|
12
|
+
const has = (value) => options.products.includes(value);
|
|
13
|
+
const existing = readJson(root, 'package.json');
|
|
14
|
+
const securityOverrides = {
|
|
15
|
+
...(has('wxt') ? { '@wxt-dev/module-react>@vitejs/plugin-react': '5.2.0' } : {}),
|
|
16
|
+
...(has('next') || has('vinext') ? { 'sharp@<0.35.5': '0.35.5' } : {}),
|
|
17
|
+
'source-map-js@<1.2.2': '1.2.2',
|
|
18
|
+
...(has('next') && options.hosting === 'cloudflare'
|
|
19
|
+
? { 'glob@>=10.2.0 <10.5.0': '10.5.0', 'glob@>=11.0.0 <11.1.0': '11.1.0' }
|
|
20
|
+
: {}),
|
|
21
|
+
...(has('wxt')
|
|
22
|
+
? { 'shell-quote@<1.12.0': '1.12.0', 'tmp@<0.2.7': '0.2.7', 'adm-zip@<0.6.1': '0.6.1' }
|
|
23
|
+
: {}),
|
|
24
|
+
'baseline-browser-mapping@<2.11.0': '2.11.27',
|
|
25
|
+
'browserslist@<4.28.7': '4.29.3',
|
|
26
|
+
...(((has('next') || has('vinext')) && options.hosting === 'cloudflare') ||
|
|
27
|
+
has('hono') ||
|
|
28
|
+
has('electron') ||
|
|
29
|
+
has('wxt')
|
|
30
|
+
? { 'esbuild@<0.25.0': '0.25.12' }
|
|
31
|
+
: {}),
|
|
32
|
+
'brace-expansion@<2': '1.1.21',
|
|
33
|
+
'brace-expansion@>=2 <3': '2.1.7',
|
|
34
|
+
'brace-expansion@>=3 <4': '3.0.9',
|
|
35
|
+
'brace-expansion@>=4 <5.0.12': '5.0.12',
|
|
36
|
+
};
|
|
37
|
+
patchPackage(root, 'package.json', {
|
|
38
|
+
name: options.name,
|
|
39
|
+
private: true,
|
|
40
|
+
packageManager: PACKAGE_MANAGER,
|
|
41
|
+
engines: { node: '>=22.13.0' },
|
|
42
|
+
scripts: {
|
|
43
|
+
dev: 'turbo dev',
|
|
44
|
+
build: 'turbo build',
|
|
45
|
+
...((has('next') || has('vinext')) && options.hosting === 'cloudflare'
|
|
46
|
+
? { 'build:worker': 'pnpm --dir apps/web run build:worker' }
|
|
47
|
+
: {}),
|
|
48
|
+
lint: 'turbo lint',
|
|
49
|
+
typecheck: 'turbo typecheck',
|
|
50
|
+
test: 'turbo test',
|
|
51
|
+
audit: 'node scripts/audit.mjs',
|
|
52
|
+
'audit:full': 'fallow --fail-on-issues',
|
|
53
|
+
'audit:deps': 'node scripts/security/audit-deps.mjs',
|
|
54
|
+
check: `pnpm lint && pnpm typecheck && pnpm run audit && pnpm audit:deps && pnpm test && pnpm build${workerBuildSuffix(options)}`,
|
|
55
|
+
},
|
|
56
|
+
devDependencies: { fallow: STACK_DEPENDENCIES['fallow'] },
|
|
57
|
+
// Upstream starter lockfiles can retain vulnerable transitive versions. Keep fixes within compatible majors.
|
|
58
|
+
pnpm: { ...existing.pnpm, overrides: { ...existing.pnpm?.overrides, ...securityOverrides } },
|
|
59
|
+
});
|
|
60
|
+
put(root, 'scripts/audit.mjs', `import { spawnSync } from 'node:child_process';
|
|
61
|
+
const base = process.env.AUDIT_BASE;
|
|
62
|
+
const hasBase = base || ['origin/main', 'main'].find((ref) => spawnSync('git', ['rev-parse', '--verify', ref], { stdio: 'ignore' }).status === 0);
|
|
63
|
+
const args = hasBase ? ['exec', 'fallow', 'audit', '--base', hasBase] : ['exec', 'fallow', '--fail-on-issues'];
|
|
64
|
+
const entry = process.env.npm_execpath;
|
|
65
|
+
if (!entry) throw new Error('Run this check through pnpm run audit.');
|
|
66
|
+
const result = spawnSync(process.execPath, [entry, ...args], { stdio: 'inherit', shell: false });
|
|
67
|
+
if (result.error) throw result.error;
|
|
68
|
+
process.exitCode = result.status ?? 1;
|
|
69
|
+
`);
|
|
70
|
+
json(root, '.fallowrc.json', {
|
|
71
|
+
...(has('electron') ? { entry: ['apps/desktop/src/main/preload.cts'] } : {}),
|
|
72
|
+
// Expo web export and NativeWind load these runtime dependencies dynamically.
|
|
73
|
+
...(has('expo')
|
|
74
|
+
? {
|
|
75
|
+
ignoreDependencies: [
|
|
76
|
+
'react-native-web',
|
|
77
|
+
'react-native-css-interop',
|
|
78
|
+
'react-native-reanimated',
|
|
79
|
+
'react-native-worklets',
|
|
80
|
+
],
|
|
81
|
+
}
|
|
82
|
+
: {}),
|
|
83
|
+
ignorePatterns: [
|
|
84
|
+
'**/next-env.d.ts',
|
|
85
|
+
'**/.next/**',
|
|
86
|
+
'**/.open-next/**',
|
|
87
|
+
'**/.wrangler/**',
|
|
88
|
+
'**/dist/**',
|
|
89
|
+
'**/worker-configuration.d.ts',
|
|
90
|
+
'**/cloudflare-env.d.ts',
|
|
91
|
+
],
|
|
92
|
+
});
|
|
93
|
+
const turbo = readJson(root, 'turbo.json');
|
|
94
|
+
turbo.globalEnv = [...new Set(registry.items.flatMap((item) => item.environment))].sort();
|
|
95
|
+
turbo.tasks = {
|
|
96
|
+
...turbo.tasks,
|
|
97
|
+
dev: { ...turbo.tasks.dev, cache: false, persistent: true },
|
|
98
|
+
lint: { ...turbo.tasks.lint, dependsOn: ['^lint'] },
|
|
99
|
+
typecheck: { ...turbo.tasks.typecheck, dependsOn: ['^typecheck'] },
|
|
100
|
+
test: { dependsOn: ['^build'], outputs: ['coverage/**'] },
|
|
101
|
+
build: {
|
|
102
|
+
...turbo.tasks.build,
|
|
103
|
+
dependsOn: [...new Set(['^build', ...(turbo.tasks.build?.dependsOn ?? [])])],
|
|
104
|
+
outputs: ['.next/**', '!.next/cache/**', '.open-next/**', 'dist/**', '.output/**'],
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
json(root, 'turbo.json', turbo);
|
|
108
|
+
setPnpmPolicy(root, {
|
|
109
|
+
allowBuilds: undefined,
|
|
110
|
+
onlyBuiltDependencies: [
|
|
111
|
+
'esbuild',
|
|
112
|
+
'sharp',
|
|
113
|
+
'unrs-resolver',
|
|
114
|
+
'workerd',
|
|
115
|
+
...(has('electron') ? ['electron'] : []),
|
|
116
|
+
],
|
|
117
|
+
});
|
|
118
|
+
writeSecurityBackports(root);
|
|
119
|
+
appendGitignore(root, [
|
|
120
|
+
'node_modules/',
|
|
121
|
+
'.open-next/',
|
|
122
|
+
'.wrangler/',
|
|
123
|
+
'.dev.vars',
|
|
124
|
+
'.dev.vars.*',
|
|
125
|
+
'!.dev.vars.example',
|
|
126
|
+
'.env',
|
|
127
|
+
'.env.*',
|
|
128
|
+
'!.env.example',
|
|
129
|
+
'.fallow/',
|
|
130
|
+
'.anhedral/',
|
|
131
|
+
]);
|
|
132
|
+
writeEnvironmentExample(root, registry);
|
|
133
|
+
json(root, 'anhedral.standard.json', {
|
|
134
|
+
schemaVersion: 1,
|
|
135
|
+
standard: 'anhedral-application-stack',
|
|
136
|
+
products: options.products,
|
|
137
|
+
hosting: has('next') || has('vinext') ? options.hosting : null,
|
|
138
|
+
bootstrap: updating
|
|
139
|
+
? readJson(root, 'anhedral.standard.json').bootstrap
|
|
140
|
+
: {
|
|
141
|
+
command: BOOTSTRAP_COMMAND.join(' '),
|
|
142
|
+
upstreamPackageManager: existing.packageManager,
|
|
143
|
+
},
|
|
144
|
+
status: 'starter',
|
|
145
|
+
resourcesProvisioned: false,
|
|
146
|
+
});
|
|
147
|
+
json(root, 'anhedral.setup.json', createSetupPlan({ ...options, dryRun: false }, registry));
|
|
148
|
+
if (!updating)
|
|
149
|
+
writeSetupDocumentation(root, options);
|
|
150
|
+
}
|
|
@@ -16,6 +16,11 @@ export function configureSecurityBackports(root) {
|
|
|
16
16
|
});
|
|
17
17
|
if (!entries.length)
|
|
18
18
|
return false;
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const workspaceFile = path.join(root, 'pnpm-workspace.yaml');
|
|
20
|
+
const before = readFileSync(workspaceFile, 'utf8');
|
|
21
|
+
mergePnpmPatches(root, Object.fromEntries(entries.map(({ name, version, patch }) => [
|
|
22
|
+
`${name}@${version}`,
|
|
23
|
+
`scripts/security/${patch}`,
|
|
24
|
+
])));
|
|
25
|
+
return readFileSync(workspaceFile, 'utf8') !== before;
|
|
21
26
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { ItemDefinition, StackRegistryItem, RecipeContext } from './registry/types.js';
|
|
2
|
+
/** Every product owns its source recipe, setup requirements and composition policy here. */
|
|
3
|
+
declare const PRODUCT_ITEMS: {
|
|
4
|
+
vinext: ItemDefinition;
|
|
5
|
+
next: ItemDefinition;
|
|
6
|
+
expo: ItemDefinition;
|
|
7
|
+
electron: ItemDefinition;
|
|
8
|
+
wxt: ItemDefinition;
|
|
9
|
+
hono: ItemDefinition;
|
|
10
|
+
neon: ItemDefinition;
|
|
11
|
+
d1: ItemDefinition;
|
|
12
|
+
'local-data': ItemDefinition;
|
|
13
|
+
clerk: ItemDefinition;
|
|
14
|
+
'better-auth': ItemDefinition;
|
|
15
|
+
r2: ItemDefinition;
|
|
16
|
+
kv: ItemDefinition;
|
|
17
|
+
realtime: ItemDefinition;
|
|
18
|
+
queues: ItemDefinition;
|
|
19
|
+
cron: ItemDefinition;
|
|
20
|
+
workflows: ItemDefinition;
|
|
21
|
+
openai: ItemDefinition;
|
|
22
|
+
'ai-sdk': ItemDefinition;
|
|
23
|
+
'workers-ai': ItemDefinition;
|
|
24
|
+
resend: ItemDefinition;
|
|
25
|
+
stripe: ItemDefinition;
|
|
26
|
+
revenuecat: ItemDefinition;
|
|
27
|
+
sentry: ItemDefinition;
|
|
28
|
+
basin: ItemDefinition;
|
|
29
|
+
posthog: ItemDefinition;
|
|
30
|
+
styling: ItemDefinition;
|
|
31
|
+
};
|
|
32
|
+
export type StandardProduct = keyof typeof PRODUCT_ITEMS;
|
|
33
|
+
export declare const STANDARD_PRODUCTS: readonly ("realtime" | "electron" | "wxt" | "expo" | "next" | "vinext" | "hono" | "neon" | "better-auth" | "queues" | "workflows" | "d1" | "local-data" | "clerk" | "r2" | "kv" | "cron" | "openai" | "ai-sdk" | "workers-ai" | "resend" | "stripe" | "revenuecat" | "sentry" | "basin" | "posthog" | "styling")[];
|
|
34
|
+
declare const DEFINITIONS: {
|
|
35
|
+
vinext: ItemDefinition;
|
|
36
|
+
next: ItemDefinition;
|
|
37
|
+
expo: ItemDefinition;
|
|
38
|
+
electron: ItemDefinition;
|
|
39
|
+
wxt: ItemDefinition;
|
|
40
|
+
hono: ItemDefinition;
|
|
41
|
+
neon: ItemDefinition;
|
|
42
|
+
d1: ItemDefinition;
|
|
43
|
+
'local-data': ItemDefinition;
|
|
44
|
+
clerk: ItemDefinition;
|
|
45
|
+
'better-auth': ItemDefinition;
|
|
46
|
+
r2: ItemDefinition;
|
|
47
|
+
kv: ItemDefinition;
|
|
48
|
+
realtime: ItemDefinition;
|
|
49
|
+
queues: ItemDefinition;
|
|
50
|
+
cron: ItemDefinition;
|
|
51
|
+
workflows: ItemDefinition;
|
|
52
|
+
openai: ItemDefinition;
|
|
53
|
+
'ai-sdk': ItemDefinition;
|
|
54
|
+
'workers-ai': ItemDefinition;
|
|
55
|
+
resend: ItemDefinition;
|
|
56
|
+
stripe: ItemDefinition;
|
|
57
|
+
revenuecat: ItemDefinition;
|
|
58
|
+
sentry: ItemDefinition;
|
|
59
|
+
basin: ItemDefinition;
|
|
60
|
+
posthog: ItemDefinition;
|
|
61
|
+
styling: ItemDefinition;
|
|
62
|
+
workspace: ItemDefinition;
|
|
63
|
+
typescript: ItemDefinition;
|
|
64
|
+
eslint: ItemDefinition;
|
|
65
|
+
ui: ItemDefinition;
|
|
66
|
+
};
|
|
67
|
+
export type StackItemId = keyof typeof DEFINITIONS;
|
|
68
|
+
export declare function getStackDefinition(name: string): ItemDefinition;
|
|
69
|
+
export declare function getStackItem(name: string): StackRegistryItem;
|
|
70
|
+
export declare const STACK_ITEMS: Record<"realtime" | "electron" | "eslint" | "typescript" | "wxt" | "expo" | "next" | "vinext" | "hono" | "neon" | "better-auth" | "queues" | "workflows" | "workspace" | "ui" | "d1" | "local-data" | "clerk" | "r2" | "kv" | "cron" | "openai" | "ai-sdk" | "workers-ai" | "resend" | "stripe" | "revenuecat" | "sentry" | "basin" | "posthog" | "styling", StackRegistryItem>;
|
|
71
|
+
export declare const STACK_REGISTRY: {
|
|
72
|
+
schemaVersion: number;
|
|
73
|
+
name: string;
|
|
74
|
+
cliVersion: string;
|
|
75
|
+
items: StackRegistryItem[];
|
|
76
|
+
};
|
|
77
|
+
export declare function installStackItem(item: StackRegistryItem, context: RecipeContext): void | Promise<void>;
|
|
78
|
+
/** Validate authored definitions during build, before shipping either catalog. */
|
|
79
|
+
export declare function validateStackCatalog(): void;
|
|
80
|
+
export {};
|