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.
Files changed (2) hide show
  1. package/dist/index.js +92 -46
  2. 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-cloudflare",
804
+ astrale: "@astrale-os/adapter-astrale",
802
805
  cloudflare: "@astrale-os/adapter-cloudflare"
803
806
  };
804
- function templateDir(adapter) {
805
- const pkg = ADAPTER_PACKAGES[adapter];
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(opts.adapter);
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 stampAdapter(opts) {
849
+ async function materializeAdapter(opts) {
850
+ if (opts.adapter !== "astrale") return;
847
851
  const config = join(opts.dir, "astrale.config.ts");
848
- if (opts.adapter === "astrale") {
849
- if (opts.instance)
850
- await replaceInFile(config, `'${INSTANCE_PLACEHOLDER}'`, `'${opts.instance}'`);
851
- return;
852
- }
853
- await replaceInFile(
854
- config,
855
- "import { astrale } from '@astrale-os/adapter-cloudflare'",
856
- "import { cloudflare } from '@astrale-os/adapter-cloudflare'"
857
- );
858
- await replaceInFile(config, "adapter: astrale({", "adapter: cloudflare({");
859
- await replaceInFile(
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", "note.ts"),
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, "methods", "index.ts"),
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 { Env } from '../env'
962
+ import type { Deps } from '../deps'
919
963
  import { schema } from '../schema'
920
964
 
921
- export const methods: SchemaMethodsImpl<typeof schema, Env> = {}
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, "schema", "compiled.ts"), { force: true });
929
- await rm(join(dir, "methods", "note.ts"), { force: true });
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", "note.ts"), { force: true });
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, "astrale.config.ts"),
935
- /\n\s*postInstall: `\/:\$\{schema\.domain\}:class\.Note:seed`,/,
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", "devkit", "package.json"));
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 "Note" class + a view + a seed'
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 instance install <url> # mount it on an instance";
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 instance install <url>`,
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.1.5",
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.1.8"
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",