create-astrale-domain 0.1.5 → 0.2.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/dist/index.js +92 -46
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -792,22 +792,24 @@ var ORIGIN_PLACEHOLDER = "astrale-domain.example.dev";
|
|
|
792
792
|
var INSTANCE_PLACEHOLDER = "my-instance-slug";
|
|
793
793
|
var LINK_TARGETS = {
|
|
794
794
|
"@astrale-os/sdk": "sdk",
|
|
795
|
-
"@astrale-os/devkit": "sdk/devkit",
|
|
796
795
|
"@astrale-os/adapter-cloudflare": "sdk/adapter-cloudflare",
|
|
796
|
+
"@astrale-os/adapter-astrale": "sdk/adapter-astrale",
|
|
797
797
|
"@astrale-os/kernel-core": "kernel/core",
|
|
798
|
-
"@astrale-os/kernel-dsl": "kernel/dsl"
|
|
798
|
+
"@astrale-os/kernel-dsl": "kernel/dsl",
|
|
799
|
+
// The client SPA consumes the real shell (createShell + the kernel client).
|
|
800
|
+
"@astrale-os/shell": "shell/packages/shell"
|
|
799
801
|
};
|
|
802
|
+
var BODY_PACKAGE = "@astrale-os/adapter-cloudflare";
|
|
800
803
|
var ADAPTER_PACKAGES = {
|
|
801
|
-
astrale: "@astrale-os/adapter-
|
|
804
|
+
astrale: "@astrale-os/adapter-astrale",
|
|
802
805
|
cloudflare: "@astrale-os/adapter-cloudflare"
|
|
803
806
|
};
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
if (!pkg) throw new Error(`No template package registered for adapter "${adapter}".`);
|
|
807
|
+
var ADAPTER_DEP_RANGE = ">=0.1.0 <1.0.0";
|
|
808
|
+
function templateDir(pkg) {
|
|
807
809
|
return join(dirname(require2.resolve(`${pkg}/package.json`)), "template");
|
|
808
810
|
}
|
|
809
811
|
async function scaffold(opts) {
|
|
810
|
-
const src = templateDir(
|
|
812
|
+
const src = templateDir(BODY_PACKAGE);
|
|
811
813
|
if (!existsSync(src)) {
|
|
812
814
|
throw new Error(`Template not found at ${src}.`);
|
|
813
815
|
}
|
|
@@ -819,9 +821,10 @@ async function scaffold(opts) {
|
|
|
819
821
|
recursive: true,
|
|
820
822
|
filter: (s) => !/\/(node_modules|\.astrale|dist-client|\.wrangler)(\/|$)/.test(`/${relative(src, s)}`)
|
|
821
823
|
});
|
|
824
|
+
await materializeAdapter(opts);
|
|
822
825
|
await stampOrigin(opts.dir, opts.origin);
|
|
823
|
-
await stampAdapter(opts);
|
|
824
826
|
await rewritePackageJson(opts.dir, opts.name, opts.link);
|
|
827
|
+
if (opts.link) await linkWorkspaceMember(join(opts.dir, "client", "package.json"));
|
|
825
828
|
await writeFile(
|
|
826
829
|
join(opts.dir, ".env.dev"),
|
|
827
830
|
"# Dev secrets \u2014 the ENTIRE file is injected into the local runtime by `pnpm dev`.\n# Gitignored. See .env.example.\n"
|
|
@@ -843,32 +846,38 @@ async function stampOrigin(dir, origin) {
|
|
|
843
846
|
const config = join(dir, "astrale.config.ts");
|
|
844
847
|
await replaceInFile(config, ORIGIN_PLACEHOLDER, origin);
|
|
845
848
|
}
|
|
846
|
-
async function
|
|
849
|
+
async function materializeAdapter(opts) {
|
|
850
|
+
if (opts.adapter !== "astrale") return;
|
|
847
851
|
const config = join(opts.dir, "astrale.config.ts");
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
config,
|
|
861
|
-
/\n \/\/ Managed deploy:[\s\S]*?prod: \{ instance: '[^']*' \},\n \/\/ Author secrets[\s\S]*?omit = keep, `\{\}` = clear\)\.\n/,
|
|
862
|
-
`
|
|
863
|
-
// Custom-domain prod. Drop \`route\` to ship to *.workers.dev instead.
|
|
864
|
-
prod: { route: '${opts.origin}', secrets: '.env.prod' },
|
|
865
|
-
`
|
|
866
|
-
);
|
|
867
|
-
await replaceInFile(
|
|
868
|
-
config,
|
|
869
|
-
/\/\/ Have your own Cloudflare account[\s\S]*?\/\/ \}\),\n/,
|
|
870
|
-
"// No Cloudflare account? Swap the adapter for the Astrale-managed one \u2014 it\n// publishes the same bundle THROUGH the platform and installs it on your\n// instance as a managed service (auth = your `astrale auth login` session):\n//\n// import { astrale } from '@astrale-os/adapter-cloudflare'\n// adapter: astrale({\n// dev: { secrets: '.env.dev' }, // local wrangler dev, unchanged\n// prod: { instance: '<your-instance-slug>' } // pnpm prod \u2192 managed deploy\n// }),\n"
|
|
852
|
+
await cp(join(templateDir(ADAPTER_PACKAGES.astrale), "astrale.config.ts"), config);
|
|
853
|
+
await setAdapterDep(opts.dir, "@astrale-os/adapter-cloudflare", "@astrale-os/adapter-astrale");
|
|
854
|
+
if (opts.instance) await replaceInFile(config, `'${INSTANCE_PLACEHOLDER}'`, `'${opts.instance}'`);
|
|
855
|
+
}
|
|
856
|
+
async function setAdapterDep(dir, from, to) {
|
|
857
|
+
const path = join(dir, "package.json");
|
|
858
|
+
const pkg = JSON.parse(await readFile(path, "utf-8"));
|
|
859
|
+
if (!pkg.dependencies || !(from in pkg.dependencies)) return;
|
|
860
|
+
delete pkg.dependencies[from];
|
|
861
|
+
pkg.dependencies[to] = ADAPTER_DEP_RANGE;
|
|
862
|
+
pkg.dependencies = Object.fromEntries(
|
|
863
|
+
Object.entries(pkg.dependencies).sort(([a], [b3]) => a.localeCompare(b3))
|
|
871
864
|
);
|
|
865
|
+
await writeFile(path, JSON.stringify(pkg, null, 2) + "\n");
|
|
866
|
+
}
|
|
867
|
+
async function linkWorkspaceMember(pkgPath) {
|
|
868
|
+
if (!existsSync(pkgPath)) return;
|
|
869
|
+
const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
|
|
870
|
+
let changed = false;
|
|
871
|
+
for (const group of [pkg.dependencies, pkg.devDependencies]) {
|
|
872
|
+
if (!group) continue;
|
|
873
|
+
for (const [dep, rel] of Object.entries(LINK_TARGETS)) {
|
|
874
|
+
if (dep in group) {
|
|
875
|
+
group[dep] = `link:${join(WORKSPACE_ROOT, rel)}`;
|
|
876
|
+
changed = true;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
if (changed) await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
872
881
|
}
|
|
873
882
|
async function rewritePackageJson(dir, name, link) {
|
|
874
883
|
const path = join(dir, "package.json");
|
|
@@ -897,7 +906,7 @@ function sdkZodVersion() {
|
|
|
897
906
|
}
|
|
898
907
|
async function blankOut(dir, origin) {
|
|
899
908
|
await writeFile(
|
|
900
|
-
join(dir, "schema", "
|
|
909
|
+
join(dir, "schema", "monitor.ts"),
|
|
901
910
|
`// Author your classes/interfaces here, then register them in schema/index.ts.
|
|
902
911
|
export {}
|
|
903
912
|
`
|
|
@@ -907,32 +916,69 @@ export {}
|
|
|
907
916
|
`import { defineSchema, KernelSchema } from '@astrale-os/kernel-core'
|
|
908
917
|
|
|
909
918
|
export const schema = defineSchema('${origin}', {
|
|
919
|
+
interfaces: {},
|
|
920
|
+
classes: {},
|
|
910
921
|
imports: [KernelSchema],
|
|
911
922
|
})
|
|
912
923
|
`
|
|
913
924
|
);
|
|
914
925
|
await writeFile(
|
|
915
|
-
join(dir, "
|
|
926
|
+
join(dir, "env.ts"),
|
|
927
|
+
`/**
|
|
928
|
+
* Worker runtime env. The adapter injects \`WORKER_URL\` and the bindings; your
|
|
929
|
+
* handlers receive this (mapped by deps.ts) as \`ctx.deps\`. Secrets from
|
|
930
|
+
* \`.env.<env>\` arrive as extra string fields here. Add typed fields as you
|
|
931
|
+
* reference new secrets/vars.
|
|
932
|
+
*/
|
|
933
|
+
export interface Env {
|
|
934
|
+
WORKER_URL?: string
|
|
935
|
+
ASSETS?: { fetch(request: Request): Promise<Response> }
|
|
936
|
+
SELF?: { fetch(request: Request): Promise<Response> }
|
|
937
|
+
VIEW_DEV_URL?: string
|
|
938
|
+
[key: string]: unknown
|
|
939
|
+
}
|
|
940
|
+
`
|
|
941
|
+
);
|
|
942
|
+
await writeFile(
|
|
943
|
+
join(dir, "deps.ts"),
|
|
944
|
+
`/**
|
|
945
|
+
* env \u2192 handler dependency container (the seam \`defineDomain({ deps })\` mounts).
|
|
946
|
+
* Passthrough by default; transform here the moment a handler should depend on a
|
|
947
|
+
* PORT (built from \`integrations/\`) instead of raw env.
|
|
948
|
+
*/
|
|
949
|
+
import type { Env } from './env'
|
|
950
|
+
|
|
951
|
+
export interface Deps extends Env {}
|
|
952
|
+
|
|
953
|
+
export function deps(env: Env): Deps {
|
|
954
|
+
return env
|
|
955
|
+
}
|
|
956
|
+
`
|
|
957
|
+
);
|
|
958
|
+
await writeFile(
|
|
959
|
+
join(dir, "runtime", "index.ts"),
|
|
916
960
|
`import type { SchemaMethodsImpl } from '@astrale-os/sdk'
|
|
917
961
|
|
|
918
|
-
import type {
|
|
962
|
+
import type { Deps } from '../deps'
|
|
919
963
|
import { schema } from '../schema'
|
|
920
964
|
|
|
921
|
-
export const methods: SchemaMethodsImpl<typeof schema,
|
|
965
|
+
export const methods: SchemaMethodsImpl<typeof schema, Deps> = { class: {} }
|
|
922
966
|
`
|
|
923
967
|
);
|
|
924
968
|
await writeFile(join(dir, "functions", "index.ts"), `export const functions = {}
|
|
925
969
|
`);
|
|
926
970
|
await writeFile(join(dir, "views", "index.ts"), `export const views = {}
|
|
927
971
|
`);
|
|
928
|
-
await rm(join(dir, "
|
|
929
|
-
await rm(join(dir, "
|
|
930
|
-
await rm(join(dir, "functions", "seed.ts"), { force: true });
|
|
972
|
+
await rm(join(dir, "core"), { recursive: true, force: true });
|
|
973
|
+
await rm(join(dir, "integrations"), { recursive: true, force: true });
|
|
931
974
|
await rm(join(dir, "views", "welcome.ts"), { force: true });
|
|
932
|
-
await rm(join(dir, "views", "
|
|
975
|
+
await rm(join(dir, "views", "status-page.ts"), { force: true });
|
|
976
|
+
await rm(join(dir, "runtime", "monitor"), { recursive: true, force: true });
|
|
977
|
+
await rm(join(dir, "runtime", "status-page"), { recursive: true, force: true });
|
|
978
|
+
await rm(join(dir, "runtime", "shared.ts"), { force: true });
|
|
933
979
|
await replaceInFile(
|
|
934
|
-
join(dir, "
|
|
935
|
-
/\n\s*postInstall: `\/:\$\{schema\.domain\}:class\.
|
|
980
|
+
join(dir, "domain.ts"),
|
|
981
|
+
/\n\s*postInstall: `\/:\$\{schema\.domain\}:class\.Monitor:seed`,/,
|
|
936
982
|
""
|
|
937
983
|
);
|
|
938
984
|
}
|
|
@@ -943,7 +989,7 @@ async function replaceInFile(path, from, to) {
|
|
|
943
989
|
if (next !== text) await writeFile(path, next);
|
|
944
990
|
}
|
|
945
991
|
function workspaceAvailable() {
|
|
946
|
-
return existsSync(join(WORKSPACE_ROOT, "sdk", "
|
|
992
|
+
return existsSync(join(WORKSPACE_ROOT, "sdk", "package.json"));
|
|
947
993
|
}
|
|
948
994
|
|
|
949
995
|
// src/index.ts
|
|
@@ -1042,7 +1088,7 @@ async function main() {
|
|
|
1042
1088
|
{
|
|
1043
1089
|
value: "template",
|
|
1044
1090
|
label: "Template",
|
|
1045
|
-
hint: 'a working "
|
|
1091
|
+
hint: 'a working "Monitor" class + a view + a seed'
|
|
1046
1092
|
},
|
|
1047
1093
|
{ value: "blank", label: "Blank" }
|
|
1048
1094
|
]
|
|
@@ -1132,10 +1178,10 @@ var prodStep = (pm, adapter, instance) => {
|
|
|
1132
1178
|
return `${cmd} ${hint}`;
|
|
1133
1179
|
};
|
|
1134
1180
|
function installStep(pm) {
|
|
1135
|
-
if (astraleOnPath()) return "astrale
|
|
1181
|
+
if (astraleOnPath()) return "astrale domain install <url> --direct # mount it on an instance";
|
|
1136
1182
|
return [
|
|
1137
1183
|
"# astrale CLI not found on PATH \u2014 run it on demand (no install):",
|
|
1138
|
-
`${DLX[pm]} @astrale-os/astrale
|
|
1184
|
+
`${DLX[pm]} @astrale-os/astrale domain install <url> --direct`,
|
|
1139
1185
|
"# or install it globally: npm i -g @astrale-os/astrale"
|
|
1140
1186
|
].join("\n");
|
|
1141
1187
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-astrale-domain",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Scaffold a standalone Astrale domain — npm create astrale-domain",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astrale",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"type": "module",
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@clack/prompts": "^0.11.0",
|
|
22
|
-
"@astrale-os/adapter-cloudflare": "^0.
|
|
22
|
+
"@astrale-os/adapter-cloudflare": "^0.2.0",
|
|
23
|
+
"@astrale-os/adapter-astrale": "^0.2.0"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@astrale-os/ox": ">=0.1.0 <1.0.0",
|