create-factory 0.3.1-alpha.4 → 0.4.0-alpha.6
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 +1 -1
- package/dist/index.js +17 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ pnpm create factory@latest
|
|
|
33
33
|
|
|
34
34
|
The interactive setup asks where to create the project and helps configure your Mastra Factory project.
|
|
35
35
|
|
|
36
|
-
By default, the setup wizard provisions Mastra platform resources during setup, enabling you to fully run Mastra Factory on platform or locally with cloud-backed capabilities. If you prefer to [self-host](https://factory.mastra.ai/deployment#self-host) Mastra Factory, run the setup with the `--no-platform` flag.
|
|
36
|
+
By default, the setup wizard scaffolds the [platform template](https://github.com/mastra-ai/template-factory) and provisions Mastra platform resources during setup, enabling you to fully run Mastra Factory on platform or locally with cloud-backed capabilities. If you prefer to [self-host](https://factory.mastra.ai/deployment#self-host) Mastra Factory, run the setup with the `--no-platform` flag. It scaffolds the [self-hosted template](https://github.com/mastra-ai/template-factory-self-hosted) instead, which uses PostgreSQL, WorkOS, a GitHub App, and local sandboxes. Either way, the setup writes a freshly generated `FACTORY_CREDENTIAL_ENCRYPTION_KEY` to `.env` when the template uses one, so stored credentials are encrypted from the first start.
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
npx create-factory@latest -- --no-platform
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { PosthogAnalytics, setAnalytics } from "mastra/dist/analytics/index.js";
|
|
7
|
+
import { randomBytes } from "node:crypto";
|
|
7
8
|
import * as p from "@clack/prompts";
|
|
8
9
|
import { LoginCancelledError, MASTRA_PLATFORM_API_URL, authHeaders, extractApiErrorDetail, fetchOrgs, getToken, loadCredentials, platformFetch, resolveCurrentOrg } from "mastra/internal/auth";
|
|
9
10
|
import color from "picocolors";
|
|
@@ -317,7 +318,6 @@ function getInstallArgs(packageManager) {
|
|
|
317
318
|
default: return ["install"];
|
|
318
319
|
}
|
|
319
320
|
}
|
|
320
|
-
// src/create.ts
|
|
321
321
|
const PROJECT_REGION_OPTIONS = [{
|
|
322
322
|
value: "eu",
|
|
323
323
|
label: "🇪🇺 eu"
|
|
@@ -357,13 +357,14 @@ async function create(args) {
|
|
|
357
357
|
const spinner = p.spinner();
|
|
358
358
|
spinner.start("Downloading the Mastra Factory template...");
|
|
359
359
|
try {
|
|
360
|
-
await cloneTemplate(args.template, projectPath);
|
|
360
|
+
await cloneTemplate(args.template ?? (args.noPlatform ? "https://github.com/mastra-ai/template-factory-self-hosted" : "https://github.com/mastra-ai/template-factory"), projectPath);
|
|
361
361
|
await renameProject(projectPath, projectName);
|
|
362
362
|
const envPath = path.join(projectPath, ".env");
|
|
363
363
|
fs.copyFileSync(path.join(projectPath, ".env.example"), envPath);
|
|
364
364
|
try {
|
|
365
365
|
fs.chmodSync(envPath, 384);
|
|
366
366
|
} catch {}
|
|
367
|
+
seedCredentialEncryptionKey(envPath);
|
|
367
368
|
spinner.stop("Template downloaded.");
|
|
368
369
|
} catch (err) {
|
|
369
370
|
spinner.stop("Template download failed.");
|
|
@@ -599,6 +600,17 @@ function sanitizeDatabaseName(projectName) {
|
|
|
599
600
|
return (projectName.replace(/[^a-zA-Z0-9_-]/g, "-").replace(/^-+|-+$/g, "") || "factory").slice(0, 64);
|
|
600
601
|
}
|
|
601
602
|
/**
|
|
603
|
+
* Fill the template's empty `FACTORY_CREDENTIAL_ENCRYPTION_KEY` placeholder
|
|
604
|
+
* with a fresh AES-256 key so stored credentials are encrypted from the first
|
|
605
|
+
* boot. Templates that don't declare the key, or that already set one, are
|
|
606
|
+
* left alone.
|
|
607
|
+
*/
|
|
608
|
+
function seedCredentialEncryptionKey(envPath) {
|
|
609
|
+
const env = fs.readFileSync(envPath, "utf8");
|
|
610
|
+
if (!/^\s*(#\s*)?FACTORY_CREDENTIAL_ENCRYPTION_KEY\s*=\s*$/m.test(env)) return;
|
|
611
|
+
upsertEnvFile(envPath, { FACTORY_CREDENTIAL_ENCRYPTION_KEY: randomBytes(32).toString("base64") });
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
602
614
|
* Append `.env` to the scaffolded project's `.gitignore` if it isn't already
|
|
603
615
|
* ignored. Runs before the initial `git add -A` so freshly-provisioned platform
|
|
604
616
|
* credentials (MASTRA_PLATFORM_SECRET_KEY, DATABASE_URL) never reach the
|
|
@@ -673,12 +685,11 @@ const analytics = new PosthogAnalytics({
|
|
|
673
685
|
});
|
|
674
686
|
setAnalytics(analytics);
|
|
675
687
|
const program = new Command();
|
|
676
|
-
|
|
677
|
-
program.name("create-factory").description("Create a new Mastra Factory project").argument("[project-name]", "Directory name of the project").option("--template <template-name>", "Create a project from a template (public GitHub URL)", DEFAULT_TEMPLATE_REPO).option("--no-platform", "Skip Mastra platform sign-in, project, and Neon provisioning").option("--org <org>", "Mastra organization id or name — skips the interactive org picker").option("--region <region>", "Platform project region (eu or us); prompts when omitted").version(pkg.version, "-v, --version").action(async (projectNameArg, args) => {
|
|
688
|
+
program.name("create-factory").description("Create a new Mastra Factory project").argument("[project-name]", "Directory name of the project").option("--template <template-name>", "Create a project from a template (public GitHub URL). Defaults to the platform template, or the self-hosted template with --no-platform").option("--no-platform", "Skip Mastra platform provisioning and scaffold the self-hosted template").option("--org <org>", "Mastra organization id or name — skips the interactive org picker").option("--region <region>", "Platform project region (eu or us); prompts when omitted").version(pkg.version, "-v, --version").action(async (projectNameArg, args) => {
|
|
678
689
|
const region = args.region ? String(args.region) : void 0;
|
|
679
690
|
const validRegion = region === "eu" || region === "us" ? region : void 0;
|
|
680
691
|
const sensitiveValues = [
|
|
681
|
-
args.template
|
|
692
|
+
args.template,
|
|
682
693
|
args.org ? String(args.org) : void 0,
|
|
683
694
|
validRegion ? void 0 : region,
|
|
684
695
|
projectNameArg
|
|
@@ -688,7 +699,7 @@ program.name("create-factory").description("Create a new Mastra Factory project"
|
|
|
688
699
|
await analytics.trackCommandExecution({
|
|
689
700
|
command: "create-factory",
|
|
690
701
|
args: {
|
|
691
|
-
default_template: args.template ===
|
|
702
|
+
default_template: args.template === void 0,
|
|
692
703
|
no_platform: args.platform === false,
|
|
693
704
|
has_org: Boolean(args.org),
|
|
694
705
|
region: validRegion ?? (region ? "invalid" : void 0)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-factory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-alpha.6",
|
|
4
4
|
"description": "Create a Mastra Factory project: an agent-powered software delivery environment built on Mastra. Run `npm create factory` to scaffold and get started.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"commander": "^14.0.3",
|
|
37
37
|
"picocolors": "^1.1.1",
|
|
38
38
|
"tinyexec": "^1.3.1",
|
|
39
|
-
"mastra": "1.36.0-alpha.
|
|
39
|
+
"mastra": "1.36.0-alpha.6"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "22.19.15",
|