hatchkit 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/dist/config.d.ts +131 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +629 -0
- package/dist/config.js.map +1 -0
- package/dist/deploy/coolify.d.ts +4 -0
- package/dist/deploy/coolify.d.ts.map +1 -0
- package/dist/deploy/coolify.js +20 -0
- package/dist/deploy/coolify.js.map +1 -0
- package/dist/deploy/github.d.ts +4 -0
- package/dist/deploy/github.d.ts.map +1 -0
- package/dist/deploy/github.js +39 -0
- package/dist/deploy/github.js.map +1 -0
- package/dist/deploy/gpu.d.ts +4 -0
- package/dist/deploy/gpu.d.ts.map +1 -0
- package/dist/deploy/gpu.js +97 -0
- package/dist/deploy/gpu.js.map +1 -0
- package/dist/deploy/keys.d.ts +9 -0
- package/dist/deploy/keys.d.ts.map +1 -0
- package/dist/deploy/keys.js +73 -0
- package/dist/deploy/keys.js.map +1 -0
- package/dist/deploy/terraform.d.ts +4 -0
- package/dist/deploy/terraform.d.ts.map +1 -0
- package/dist/deploy/terraform.js +55 -0
- package/dist/deploy/terraform.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +599 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +52 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +313 -0
- package/dist/prompts.js.map +1 -0
- package/dist/provision/glitchtip.d.ts +6 -0
- package/dist/provision/glitchtip.d.ts.map +1 -0
- package/dist/provision/glitchtip.js +46 -0
- package/dist/provision/glitchtip.js.map +1 -0
- package/dist/provision/index.d.ts +9 -0
- package/dist/provision/index.d.ts.map +1 -0
- package/dist/provision/index.js +108 -0
- package/dist/provision/index.js.map +1 -0
- package/dist/provision/openpanel.d.ts +8 -0
- package/dist/provision/openpanel.d.ts.map +1 -0
- package/dist/provision/openpanel.js +66 -0
- package/dist/provision/openpanel.js.map +1 -0
- package/dist/provision/resend.d.ts +16 -0
- package/dist/provision/resend.d.ts.map +1 -0
- package/dist/provision/resend.js +43 -0
- package/dist/provision/resend.js.map +1 -0
- package/dist/scaffold/app.d.ts +13 -0
- package/dist/scaffold/app.d.ts.map +1 -0
- package/dist/scaffold/app.js +340 -0
- package/dist/scaffold/app.js.map +1 -0
- package/dist/scaffold/dotenvx.d.ts +30 -0
- package/dist/scaffold/dotenvx.d.ts.map +1 -0
- package/dist/scaffold/dotenvx.js +142 -0
- package/dist/scaffold/dotenvx.js.map +1 -0
- package/dist/scaffold/infra.d.ts +17 -0
- package/dist/scaffold/infra.d.ts.map +1 -0
- package/dist/scaffold/infra.js +200 -0
- package/dist/scaffold/infra.js.map +1 -0
- package/dist/scaffold/manifest.d.ts +50 -0
- package/dist/scaffold/manifest.d.ts.map +1 -0
- package/dist/scaffold/manifest.js +83 -0
- package/dist/scaffold/manifest.js.map +1 -0
- package/dist/scaffold/ml-client.d.ts +20 -0
- package/dist/scaffold/ml-client.d.ts.map +1 -0
- package/dist/scaffold/ml-client.js +38 -0
- package/dist/scaffold/ml-client.js.map +1 -0
- package/dist/scaffold/pkg-json.d.ts +20 -0
- package/dist/scaffold/pkg-json.d.ts.map +1 -0
- package/dist/scaffold/pkg-json.js +113 -0
- package/dist/scaffold/pkg-json.js.map +1 -0
- package/dist/scaffold/starter-files.d.ts +40 -0
- package/dist/scaffold/starter-files.d.ts.map +1 -0
- package/dist/scaffold/starter-files.js +197 -0
- package/dist/scaffold/starter-files.js.map +1 -0
- package/dist/scaffold/update.d.ts +8 -0
- package/dist/scaffold/update.d.ts.map +1 -0
- package/dist/scaffold/update.js +255 -0
- package/dist/scaffold/update.js.map +1 -0
- package/dist/templates/addons/analytics/middleware.ts.hbs +13 -0
- package/dist/templates/addons/analytics/sentry.ts.hbs +16 -0
- package/dist/templates/addons/storage/s3.ts.hbs +40 -0
- package/dist/templates/addons/storage/upload.ts.hbs +23 -0
- package/dist/templates/addons/stripe/checkout.ts.hbs +27 -0
- package/dist/templates/addons/stripe/client.ts.hbs +6 -0
- package/dist/templates/addons/stripe/webhook.ts.hbs +39 -0
- package/dist/templates/addons/websocket/redis.ts.hbs +25 -0
- package/dist/templates/addons/websocket/ws.ts.hbs +32 -0
- package/dist/templates/base/.dockerignore.hbs +7 -0
- package/dist/templates/base/Dockerfile.hbs +18 -0
- package/dist/templates/base/env.example.hbs +60 -0
- package/dist/templates/base/github-actions.yml.hbs +35 -0
- package/dist/templates/base/gitignore.hbs +5 -0
- package/dist/templates/base/package.json.hbs +36 -0
- package/dist/templates/base/src/auth/auth.ts.hbs +13 -0
- package/dist/templates/base/src/auth/routes.ts.hbs +19 -0
- package/dist/templates/base/src/config.ts.hbs +36 -0
- package/dist/templates/base/src/db.ts.hbs +12 -0
- package/dist/templates/base/src/index.ts.hbs +80 -0
- package/dist/templates/base/src/routes/health.ts.hbs +12 -0
- package/dist/templates/base/tsconfig.json.hbs +18 -0
- package/dist/templates/ml-clients/3d-extraction.ts.hbs +20 -0
- package/dist/templates/ml-clients/background-removal.ts.hbs +17 -0
- package/dist/templates/ml-clients/custom-hf.ts.hbs +20 -0
- package/dist/templates/ml-clients/image-recognition.ts.hbs +22 -0
- package/dist/templates/ml-clients/subtitles.ts.hbs +26 -0
- package/dist/utils/coolify-api.d.ts +45 -0
- package/dist/utils/coolify-api.d.ts.map +1 -0
- package/dist/utils/coolify-api.js +72 -0
- package/dist/utils/coolify-api.js.map +1 -0
- package/dist/utils/errors.d.ts +2 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +31 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/exec.d.ts +23 -0
- package/dist/utils/exec.d.ts.map +1 -0
- package/dist/utils/exec.js +47 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/flags.d.ts +17 -0
- package/dist/utils/flags.d.ts.map +1 -0
- package/dist/utils/flags.js +116 -0
- package/dist/utils/flags.js.map +1 -0
- package/dist/utils/hf-api.d.ts +13 -0
- package/dist/utils/hf-api.d.ts.map +1 -0
- package/dist/utils/hf-api.js +30 -0
- package/dist/utils/hf-api.js.map +1 -0
- package/dist/utils/ports.d.ts +29 -0
- package/dist/utils/ports.d.ts.map +1 -0
- package/dist/utils/ports.js +86 -0
- package/dist/utils/ports.js.map +1 -0
- package/dist/utils/secrets.d.ts +25 -0
- package/dist/utils/secrets.d.ts.map +1 -0
- package/dist/utils/secrets.js +51 -0
- package/dist/utils/secrets.js.map +1 -0
- package/dist/utils/template.d.ts +7 -0
- package/dist/utils/template.d.ts.map +1 -0
- package/dist/utils/template.js +35 -0
- package/dist/utils/template.js.map +1 -0
- package/dist/utils/validate.d.ts +16 -0
- package/dist/utils/validate.d.ts.map +1 -0
- package/dist/utils/validate.js +60 -0
- package/dist/utils/validate.js.map +1 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +21 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +48 -0
- package/scripts/copy-templates.mjs +20 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* OpenPanel provisioning — creates a project + a client (write key
|
|
3
|
+
* pair) inside an existing self-hosted OpenPanel instance.
|
|
4
|
+
*
|
|
5
|
+
* OpenPanel's self-hosted API is still evolving, so this uses a
|
|
6
|
+
* best-effort path and falls back to a paste-in flow if the API call
|
|
7
|
+
* fails. Either way the resulting client id/secret are cached in the
|
|
8
|
+
* keychain under `openpanel:<name>:client-secret` so re-runs are idempotent.
|
|
9
|
+
*/
|
|
10
|
+
import { input, password as passwordPrompt } from "@inquirer/prompts";
|
|
11
|
+
import { ensureOpenpanel } from "../config.js";
|
|
12
|
+
import { SECRET_KEYS, getSecret, setSecret } from "../utils/secrets.js";
|
|
13
|
+
export async function provisionOpenpanelClient(clientName) {
|
|
14
|
+
const cfg = await ensureOpenpanel();
|
|
15
|
+
const { url, organizationSlug, token } = cfg;
|
|
16
|
+
if (!organizationSlug) {
|
|
17
|
+
throw new Error("OpenPanel config is missing organization slug. Re-run `hatchkit config add openpanel`.");
|
|
18
|
+
}
|
|
19
|
+
// Reuse a previously-provisioned client for the same name if one
|
|
20
|
+
// exists — lets you re-run the command without creating duplicates.
|
|
21
|
+
const cachedSecret = await getSecret(SECRET_KEYS.openpanelClientSecret(clientName));
|
|
22
|
+
const cachedIdKey = SECRET_KEYS.openpanelClientSecret(`${clientName}:id`);
|
|
23
|
+
const cachedId = await getSecret(cachedIdKey);
|
|
24
|
+
if (cachedSecret && cachedId) {
|
|
25
|
+
return { projectName: clientName, clientId: cachedId, clientSecret: cachedSecret, apiUrl: url };
|
|
26
|
+
}
|
|
27
|
+
// Try the API first (best-effort). If it fails, prompt the user to
|
|
28
|
+
// paste the values from the OpenPanel dashboard.
|
|
29
|
+
let clientId = null;
|
|
30
|
+
let clientSecret = null;
|
|
31
|
+
try {
|
|
32
|
+
const res = await fetch(`${url}/api/client`, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `Bearer ${token}`,
|
|
36
|
+
"Content-Type": "application/json",
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
organizationSlug,
|
|
40
|
+
project: { name: clientName },
|
|
41
|
+
client: { name: clientName, type: "write" },
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
if (res.ok) {
|
|
45
|
+
const body = (await res.json());
|
|
46
|
+
if (body.clientId && body.clientSecret) {
|
|
47
|
+
clientId = body.clientId;
|
|
48
|
+
clientSecret = body.clientSecret;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// fall through to paste flow
|
|
54
|
+
}
|
|
55
|
+
if (!clientId || !clientSecret) {
|
|
56
|
+
console.log(` OpenPanel API couldn't auto-create the client for '${clientName}'.\n` +
|
|
57
|
+
` Open ${url}/${organizationSlug} → create a project named "${clientName}" →\n` +
|
|
58
|
+
` add a write client, then paste the credentials below.`);
|
|
59
|
+
clientId = await input({ message: `OpenPanel clientId for ${clientName}:` });
|
|
60
|
+
clientSecret = await passwordPrompt({ message: `OpenPanel clientSecret for ${clientName}:` });
|
|
61
|
+
}
|
|
62
|
+
await setSecret(SECRET_KEYS.openpanelClientSecret(clientName), clientSecret);
|
|
63
|
+
await setSecret(cachedIdKey, clientId);
|
|
64
|
+
return { projectName: clientName, clientId, clientSecret, apiUrl: url };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=openpanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openpanel.js","sourceRoot":"","sources":["../../src/provision/openpanel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ResendClient {
|
|
2
|
+
keyName: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
domainId?: string;
|
|
5
|
+
/** The full API key is only returned by Resend once; we print it
|
|
6
|
+
* inline and also return it so the caller can persist. */
|
|
7
|
+
raw: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function provisionResendClient(clientName: string, domainId?: string): Promise<ResendClient>;
|
|
10
|
+
/** List verified Resend domains so the caller can pick one. */
|
|
11
|
+
export declare function listResendDomains(): Promise<Array<{
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
status: string;
|
|
15
|
+
}>>;
|
|
16
|
+
//# sourceMappingURL=resend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resend.d.ts","sourceRoot":"","sources":["../../src/provision/resend.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;+DAC2D;IAC3D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CAsBvB;AAED,+DAA+D;AAC/D,wBAAsB,iBAAiB,IAAI,OAAO,CAChD,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CACpD,CAQA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Resend provisioning — creates a restricted API key scoped to a
|
|
3
|
+
* specific verified sending domain. One key per env (dev / prod)
|
|
4
|
+
* keeps blast radius small if either leaks.
|
|
5
|
+
*
|
|
6
|
+
* API: https://resend.com/docs/api-reference/api-keys/create-api-key
|
|
7
|
+
* POST /api-keys { name, permission: "sending_access", domain_id }
|
|
8
|
+
*/
|
|
9
|
+
import { ensureResend } from "../config.js";
|
|
10
|
+
export async function provisionResendClient(clientName, domainId) {
|
|
11
|
+
const cfg = await ensureResend();
|
|
12
|
+
const body = {
|
|
13
|
+
name: clientName,
|
|
14
|
+
permission: "sending_access",
|
|
15
|
+
};
|
|
16
|
+
if (domainId)
|
|
17
|
+
body.domain_id = domainId;
|
|
18
|
+
const res = await fetch("https://api.resend.com/api-keys", {
|
|
19
|
+
method: "POST",
|
|
20
|
+
headers: {
|
|
21
|
+
Authorization: `Bearer ${cfg.apiKey}`,
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
},
|
|
24
|
+
body: JSON.stringify(body),
|
|
25
|
+
});
|
|
26
|
+
if (!res.ok) {
|
|
27
|
+
throw new Error(`Resend create key failed: HTTP ${res.status} ${await res.text()}`);
|
|
28
|
+
}
|
|
29
|
+
const data = (await res.json());
|
|
30
|
+
return { keyName: clientName, apiKey: data.token, domainId, raw: data.token };
|
|
31
|
+
}
|
|
32
|
+
/** List verified Resend domains so the caller can pick one. */
|
|
33
|
+
export async function listResendDomains() {
|
|
34
|
+
const cfg = await ensureResend();
|
|
35
|
+
const res = await fetch("https://api.resend.com/domains", {
|
|
36
|
+
headers: { Authorization: `Bearer ${cfg.apiKey}` },
|
|
37
|
+
});
|
|
38
|
+
if (!res.ok)
|
|
39
|
+
throw new Error(`Resend list domains failed: HTTP ${res.status}`);
|
|
40
|
+
const body = (await res.json());
|
|
41
|
+
return body.data ?? [];
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=resend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resend.js","sourceRoot":"","sources":["../../src/provision/resend.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAW5C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAkB,EAClB,QAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC;IAEjC,MAAM,IAAI,GAA4B;QACpC,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,gBAAgB;KAC7B,CAAC;IACF,IAAI,QAAQ;QAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,iCAAiC,EAAE;QACzD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE;YACrC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkC,CAAC;IACjE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AAChF,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,iBAAiB;IAGrC,MAAM,GAAG,GAAG,MAAM,YAAY,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gCAAgC,EAAE;QACxD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE,EAAE;KACnD,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkE,CAAC;IACjG,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ProjectConfig } from "../prompts.js";
|
|
2
|
+
import { type ProjectPorts } from "../utils/ports.js";
|
|
3
|
+
import { type DotenvxSeedResult } from "./dotenvx.js";
|
|
4
|
+
export interface ScaffoldResult {
|
|
5
|
+
modifications: string[];
|
|
6
|
+
ports: ProjectPorts;
|
|
7
|
+
/** Populated by seedDotenvxProduction on real (non-dry-run) scaffolds.
|
|
8
|
+
* The private key is also mirrored into the OS keychain. */
|
|
9
|
+
dotenvx?: DotenvxSeedResult;
|
|
10
|
+
}
|
|
11
|
+
/** Scaffold a new app by copying the starter template and customizing it. */
|
|
12
|
+
export declare function scaffoldApp(config: ProjectConfig, outputDir: string): Promise<ScaffoldResult>;
|
|
13
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/scaffold/app.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAE,KAAK,YAAY,EAAoB,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,KAAK,iBAAiB,EAAyB,MAAM,cAAc,CAAC;AAqB7E,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;IACpB;iEAC6D;IAC7D,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B;AAED,6EAA6E;AAC7E,wBAAsB,WAAW,CAC/B,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CA8FzB"}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* scaffoldApp orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities in order:
|
|
5
|
+
* 1. Validate preconditions (starter submodule present, target empty).
|
|
6
|
+
* 2. Copy the starter template to `outputDir` (fs cpSync with filter).
|
|
7
|
+
* 3. Customize the copy: project name, env files, feature flag strip,
|
|
8
|
+
* bundle IDs, port assignment + propagation, ML playground prune,
|
|
9
|
+
* next.config for static export when native is selected.
|
|
10
|
+
* 4. Roll back (rm output dir + unregister reserved ports) if any
|
|
11
|
+
* step after the copy throws.
|
|
12
|
+
*
|
|
13
|
+
* The actual file-rewriting logic lives in starter-files.ts and
|
|
14
|
+
* pkg-json.ts; this file is the control flow.
|
|
15
|
+
*/
|
|
16
|
+
import { cpSync, existsSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync, } from "node:fs";
|
|
17
|
+
import { join, resolve } from "node:path";
|
|
18
|
+
import chalk from "chalk";
|
|
19
|
+
import ora from "ora";
|
|
20
|
+
import { addUsedPorts, getUsedPorts, removeUsedPorts } from "../config.js";
|
|
21
|
+
import { explainFsError } from "../utils/errors.js";
|
|
22
|
+
import { pickProjectPorts } from "../utils/ports.js";
|
|
23
|
+
import { getCliVersion } from "../utils/version.js";
|
|
24
|
+
import { seedDotenvxProduction } from "./dotenvx.js";
|
|
25
|
+
import { MANIFEST_FILENAME, toManifest, writeManifest } from "./manifest.js";
|
|
26
|
+
import { stripPackageJsonBuildBlock, stripPackageJsonDeps, stripPackageJsonScripts, unchainTypecheckScript, } from "./pkg-json.js";
|
|
27
|
+
import { applyPorts, flipNextConfigToStaticExport, removeIfExists, replaceInFile, stripMobileBridgeFromLayout, updateEnvExample, } from "./starter-files.js";
|
|
28
|
+
// Monorepo root → starter submodule
|
|
29
|
+
const MONOREPO_ROOT = resolve(join(import.meta.dirname, "..", "..", ".."));
|
|
30
|
+
const STARTER_ROOT = join(MONOREPO_ROOT, "starter");
|
|
31
|
+
/** Scaffold a new app by copying the starter template and customizing it. */
|
|
32
|
+
export async function scaffoldApp(config, outputDir) {
|
|
33
|
+
if (config.dryRun) {
|
|
34
|
+
return {
|
|
35
|
+
modifications: scaffoldDryRun(config, outputDir),
|
|
36
|
+
// Dry-run still picks ports so the summary is accurate, but
|
|
37
|
+
// doesn't persist them.
|
|
38
|
+
ports: await pickProjectPorts(getUsedPorts(), {
|
|
39
|
+
nativeHmr: config.features.includes("desktop") || config.features.includes("mobile"),
|
|
40
|
+
}),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (!existsSync(STARTER_ROOT)) {
|
|
44
|
+
throw new Error(`Starter template not found at ${STARTER_ROOT}. Run 'git submodule update --init' in the monorepo root.`);
|
|
45
|
+
}
|
|
46
|
+
// Bail if the target already exists — without this, cpSync silently
|
|
47
|
+
// merges new files into whatever is there, mixing old and new state.
|
|
48
|
+
if (existsSync(outputDir)) {
|
|
49
|
+
const entries = readdirSync(outputDir);
|
|
50
|
+
if (entries.length > 0) {
|
|
51
|
+
// If the target looks like a previously-scaffolded project,
|
|
52
|
+
// nudge the user toward `update` instead of a hard fail.
|
|
53
|
+
const hasManifest = entries.includes(MANIFEST_FILENAME);
|
|
54
|
+
const hint = hasManifest
|
|
55
|
+
? ` This looks like a previously-scaffolded project (${MANIFEST_FILENAME} is present). Try \`hatchkit update\` from inside it to add features.`
|
|
56
|
+
: "";
|
|
57
|
+
throw new Error(`Output directory ${outputDir} already exists and is not empty. Move or remove it first.${hint}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Resolve symlinks — if the submodule path is itself a symlink (tests,
|
|
61
|
+
// local dev linking to a sibling checkout), cpSync would otherwise try
|
|
62
|
+
// to recreate the symlink at outputDir and fail with EEXIST.
|
|
63
|
+
const resolvedStarter = realpathSync(STARTER_ROOT);
|
|
64
|
+
// Track claimed resources so a mid-scaffold failure can be rolled
|
|
65
|
+
// back: filesystem + port registrations.
|
|
66
|
+
const reservedPorts = [];
|
|
67
|
+
const rollback = () => {
|
|
68
|
+
if (existsSync(outputDir)) {
|
|
69
|
+
try {
|
|
70
|
+
rmSync(outputDir, { recursive: true, force: true });
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
/* ignore */
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (reservedPorts.length > 0) {
|
|
77
|
+
try {
|
|
78
|
+
removeUsedPorts(reservedPorts);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
/* ignore */
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const copyStart = Date.now();
|
|
86
|
+
const copySpinner = ora(`Copying starter from ${resolvedStarter}`).start();
|
|
87
|
+
try {
|
|
88
|
+
cpSync(resolvedStarter, outputDir, {
|
|
89
|
+
recursive: true,
|
|
90
|
+
filter: (src) => {
|
|
91
|
+
const rel = src.replace(resolvedStarter, "");
|
|
92
|
+
if (rel === "/.git" || rel.startsWith("/.git/"))
|
|
93
|
+
return false;
|
|
94
|
+
if (rel.includes("/node_modules"))
|
|
95
|
+
return false;
|
|
96
|
+
if (rel.includes("/.next"))
|
|
97
|
+
return false;
|
|
98
|
+
if (rel.includes("/dist/"))
|
|
99
|
+
return false;
|
|
100
|
+
return true;
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
copySpinner.succeed(`Starter copied (${elapsed(copyStart)})`);
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
copySpinner.fail("Starter copy failed");
|
|
107
|
+
rollback();
|
|
108
|
+
throw new Error(explainFsError(err, "Failed to copy starter template"));
|
|
109
|
+
}
|
|
110
|
+
const customizeStart = Date.now();
|
|
111
|
+
const customizeSpinner = ora("Customizing for your project").start();
|
|
112
|
+
try {
|
|
113
|
+
const result = await runScaffoldSteps(config, outputDir, reservedPorts);
|
|
114
|
+
customizeSpinner.succeed(`Scaffolded ${result.modifications.length} modifications (${elapsed(customizeStart)})`);
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
customizeSpinner.fail("Customization failed");
|
|
119
|
+
rollback();
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Format ms-since-start as a compact "123ms" or "1.4s". */
|
|
124
|
+
function elapsed(startMs) {
|
|
125
|
+
const ms = Date.now() - startMs;
|
|
126
|
+
return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`;
|
|
127
|
+
}
|
|
128
|
+
/** Customize the starter copy. Mutates `reservedPorts` in place so the
|
|
129
|
+
* outer orchestrator can unregister them on failure. */
|
|
130
|
+
async function runScaffoldSteps(config, outputDir, reservedPorts) {
|
|
131
|
+
const modifications = [];
|
|
132
|
+
// Rename the project in package.json
|
|
133
|
+
replaceInFile(join(outputDir, "package.json"), "node-realtime-starter", config.name);
|
|
134
|
+
modifications.push("package.json (renamed project)");
|
|
135
|
+
// .env.example files: production URLs for this project's domain.
|
|
136
|
+
// .env.development is left alone (local dev defaults should stay pointing at localhost).
|
|
137
|
+
updateEnvExample(outputDir, "packages/server/.env.example", config);
|
|
138
|
+
updateEnvExample(outputDir, "packages/client/.env.example", config);
|
|
139
|
+
modifications.push("updated .env.example files with production URLs");
|
|
140
|
+
// Feature-flag removal
|
|
141
|
+
if (!config.features.includes("websocket")) {
|
|
142
|
+
removeIfExists(join(outputDir, "packages/server/src/ws"));
|
|
143
|
+
modifications.push("removed: ws/ (WebSocket not selected)");
|
|
144
|
+
}
|
|
145
|
+
if (!config.features.includes("stripe")) {
|
|
146
|
+
removeIfExists(join(outputDir, "packages/server/src/services/stripe.ts"));
|
|
147
|
+
modifications.push("removed: stripe service (Stripe not selected)");
|
|
148
|
+
}
|
|
149
|
+
const wantsDesktop = config.features.includes("desktop");
|
|
150
|
+
const wantsMobile = config.features.includes("mobile");
|
|
151
|
+
const bundleId = config.name.replace(/[^a-z0-9]/gi, "").toLowerCase();
|
|
152
|
+
// Port assignment — tested-free via isPortFree + persisted into the
|
|
153
|
+
// CLI registry so subsequent scaffolds can't collide.
|
|
154
|
+
const ports = await pickProjectPorts(getUsedPorts(), {
|
|
155
|
+
nativeHmr: wantsDesktop || wantsMobile,
|
|
156
|
+
});
|
|
157
|
+
const claimed = [ports.server, ports.client, ports.nativeHmr].filter((p) => p !== undefined);
|
|
158
|
+
addUsedPorts(claimed);
|
|
159
|
+
reservedPorts.push(...claimed);
|
|
160
|
+
applyPorts(outputDir, ports, { wantsDesktop, wantsMobile });
|
|
161
|
+
modifications.push(`assigned ports: server=${ports.server} client=${ports.client}` +
|
|
162
|
+
(ports.nativeHmr ? ` native=${ports.nativeHmr}` : ""));
|
|
163
|
+
// Desktop (Electron) strip / substitute
|
|
164
|
+
if (!wantsDesktop) {
|
|
165
|
+
removeIfExists(join(outputDir, "electron"));
|
|
166
|
+
removeIfExists(join(outputDir, ".github/workflows/desktop-release.yml"));
|
|
167
|
+
removeIfExists(join(outputDir, "build"));
|
|
168
|
+
removeIfExists(join(outputDir, "packages/client/src/types/electron.d.ts"));
|
|
169
|
+
stripPackageJsonScripts(outputDir, [
|
|
170
|
+
"dev:desktop",
|
|
171
|
+
"dev:electron",
|
|
172
|
+
"build:desktop",
|
|
173
|
+
"electron:compile",
|
|
174
|
+
"electron:build",
|
|
175
|
+
"electron:preview",
|
|
176
|
+
"typecheck:electron",
|
|
177
|
+
"icons:desktop",
|
|
178
|
+
"itch:push:mac",
|
|
179
|
+
"itch:push:win",
|
|
180
|
+
"itch:push:linux",
|
|
181
|
+
]);
|
|
182
|
+
unchainTypecheckScript(outputDir);
|
|
183
|
+
stripPackageJsonBuildBlock(outputDir);
|
|
184
|
+
stripPackageJsonDeps(outputDir, [
|
|
185
|
+
"electron",
|
|
186
|
+
"electron-builder",
|
|
187
|
+
"electron-icon-builder",
|
|
188
|
+
"wait-on",
|
|
189
|
+
]);
|
|
190
|
+
modifications.push("removed: desktop (Electron) scaffolding");
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
replaceInFile(join(outputDir, "package.json"), "{{projectName}}", config.name);
|
|
194
|
+
replaceInFile(join(outputDir, "package.json"), "{{bundleId}}", bundleId);
|
|
195
|
+
}
|
|
196
|
+
// Mobile (Capacitor) strip / substitute
|
|
197
|
+
if (!wantsMobile) {
|
|
198
|
+
removeIfExists(join(outputDir, "ios"));
|
|
199
|
+
removeIfExists(join(outputDir, "android"));
|
|
200
|
+
removeIfExists(join(outputDir, "capacitor.config.ts"));
|
|
201
|
+
removeIfExists(join(outputDir, "packages/client/src/mobile"));
|
|
202
|
+
removeIfExists(join(outputDir, "scripts/android-dev.sh"));
|
|
203
|
+
removeIfExists(join(outputDir, "scripts/android-env.sh"));
|
|
204
|
+
removeIfExists(join(outputDir, "scripts/ios-dev.sh"));
|
|
205
|
+
removeIfExists(join(outputDir, ".github/workflows/mobile-release.yml"));
|
|
206
|
+
removeIfExists(join(outputDir, "resources"));
|
|
207
|
+
stripMobileBridgeFromLayout(outputDir);
|
|
208
|
+
stripPackageJsonScripts(outputDir, [
|
|
209
|
+
"dev:android",
|
|
210
|
+
"dev:ios",
|
|
211
|
+
"build:mobile",
|
|
212
|
+
"cap:add:ios",
|
|
213
|
+
"cap:add:android",
|
|
214
|
+
"cap:sync",
|
|
215
|
+
"cap:run:ios",
|
|
216
|
+
"cap:run:android",
|
|
217
|
+
"build:ios:release",
|
|
218
|
+
"build:android:release",
|
|
219
|
+
"build:android:apk",
|
|
220
|
+
"mobile:assets",
|
|
221
|
+
]);
|
|
222
|
+
stripPackageJsonDeps(outputDir, [
|
|
223
|
+
"@capacitor/core",
|
|
224
|
+
"@capacitor/cli",
|
|
225
|
+
"@capacitor/ios",
|
|
226
|
+
"@capacitor/android",
|
|
227
|
+
"@capacitor/splash-screen",
|
|
228
|
+
"@capacitor/status-bar",
|
|
229
|
+
"@capacitor/screen-orientation",
|
|
230
|
+
"@capacitor/preferences",
|
|
231
|
+
"@capacitor/app",
|
|
232
|
+
"@capacitor/assets",
|
|
233
|
+
]);
|
|
234
|
+
modifications.push("removed: mobile (Capacitor) scaffolding");
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
replaceInFile(join(outputDir, "capacitor.config.ts"), "{{projectName}}", config.name);
|
|
238
|
+
replaceInFile(join(outputDir, "capacitor.config.ts"), "{{bundleId}}", bundleId);
|
|
239
|
+
}
|
|
240
|
+
if (wantsDesktop || wantsMobile) {
|
|
241
|
+
flipNextConfigToStaticExport(outputDir);
|
|
242
|
+
modifications.push("next.config.ts: output 'standalone' → 'export'");
|
|
243
|
+
}
|
|
244
|
+
// ML playground prune — remove unselected service pages.
|
|
245
|
+
const allMlServices = [
|
|
246
|
+
"background-removal",
|
|
247
|
+
"subtitles",
|
|
248
|
+
"image-recognition",
|
|
249
|
+
"3d-extraction",
|
|
250
|
+
];
|
|
251
|
+
for (const service of allMlServices) {
|
|
252
|
+
if (!config.mlServices.includes(service)) {
|
|
253
|
+
removeIfExists(join(outputDir, `packages/client/src/app/(protected)/playground/${service}`));
|
|
254
|
+
modifications.push(`removed: playground/${service} (not selected)`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// No ML services at all → remove the entire playground + infrastructure.
|
|
258
|
+
if (config.mlServices.length === 0) {
|
|
259
|
+
removeIfExists(join(outputDir, "packages/client/src/app/(protected)/playground"));
|
|
260
|
+
removeIfExists(join(outputDir, "packages/client/src/components/ml"));
|
|
261
|
+
removeIfExists(join(outputDir, "packages/server/src/trpc/routers/ml.ts"));
|
|
262
|
+
removeIfExists(join(outputDir, "packages/server/src/services/ml.ts"));
|
|
263
|
+
removeIfExists(join(outputDir, "packages/shared/src/ml-types.ts"));
|
|
264
|
+
// Strip ml router from the tRPC router registration.
|
|
265
|
+
const routerPath = join(outputDir, "packages/server/src/trpc/router.ts");
|
|
266
|
+
if (existsSync(routerPath)) {
|
|
267
|
+
let content = readFileSync(routerPath, "utf-8");
|
|
268
|
+
content = content.replace('import { mlRouter } from "./routers/ml.js";\n', "");
|
|
269
|
+
content = content.replace(" ml: mlRouter,\n", "");
|
|
270
|
+
writeFileSync(routerPath, content, "utf-8");
|
|
271
|
+
}
|
|
272
|
+
// Strip ml-types export from shared barrel.
|
|
273
|
+
const sharedIndexPath = join(outputDir, "packages/shared/src/index.ts");
|
|
274
|
+
if (existsSync(sharedIndexPath)) {
|
|
275
|
+
let content = readFileSync(sharedIndexPath, "utf-8");
|
|
276
|
+
content = content.replace('export * from "./ml-types.js";\n', "");
|
|
277
|
+
writeFileSync(sharedIndexPath, content, "utf-8");
|
|
278
|
+
}
|
|
279
|
+
// Strip Playground from protected navbar.
|
|
280
|
+
const layoutPath = join(outputDir, "packages/client/src/app/(protected)/layout.tsx");
|
|
281
|
+
if (existsSync(layoutPath)) {
|
|
282
|
+
let content = readFileSync(layoutPath, "utf-8");
|
|
283
|
+
content = content.replace(/\s*<Link\s+href="\/playground"[^>]*>[^<]*<\/Link>/, "");
|
|
284
|
+
writeFileSync(layoutPath, content, "utf-8");
|
|
285
|
+
}
|
|
286
|
+
modifications.push("removed: ML playground, ML router, ML types, ML navbar link");
|
|
287
|
+
}
|
|
288
|
+
// Write the sanitized manifest so `hatchkit update` can diff
|
|
289
|
+
// against this scaffold's choices later. See manifest.ts for the
|
|
290
|
+
// strict list of fields that are safe to persist.
|
|
291
|
+
writeManifest(outputDir, toManifest(config, ports, getCliVersion()));
|
|
292
|
+
modifications.push(".hatchkit.json (project manifest)");
|
|
293
|
+
// Seed .env.production via dotenvx: encrypt supplied values, mint a
|
|
294
|
+
// keypair, mirror the private key into the OS keychain. Unsupplied
|
|
295
|
+
// keys land as plaintext CHANGE_ME_<KEY> placeholders.
|
|
296
|
+
const dotenvx = await seedDotenvxProduction(outputDir, config, config.envValues ?? {});
|
|
297
|
+
modifications.push(`dotenvx: ${dotenvx.encryptedKeys.length} encrypted, ${dotenvx.placeholderKeys.length} placeholders`);
|
|
298
|
+
return { modifications, ports, dotenvx };
|
|
299
|
+
}
|
|
300
|
+
/** Dry run — list what would happen without touching disk. */
|
|
301
|
+
function scaffoldDryRun(config, outputDir) {
|
|
302
|
+
console.log(chalk.bold("\n [dry-run] Would scaffold from starter template:\n"));
|
|
303
|
+
console.log(chalk.dim(` Source: ${STARTER_ROOT}`));
|
|
304
|
+
console.log(chalk.dim(` Target: ${outputDir}`));
|
|
305
|
+
console.log();
|
|
306
|
+
const actions = [];
|
|
307
|
+
actions.push("Copy starter template");
|
|
308
|
+
actions.push(`Rename project to "${config.name}"`);
|
|
309
|
+
actions.push(`Set domain to "${config.domain}"`);
|
|
310
|
+
if (!config.features.includes("websocket"))
|
|
311
|
+
actions.push("Remove WebSocket support");
|
|
312
|
+
if (!config.features.includes("stripe"))
|
|
313
|
+
actions.push("Remove Stripe integration");
|
|
314
|
+
if (!config.features.includes("desktop"))
|
|
315
|
+
actions.push("Remove desktop (Electron) scaffolding");
|
|
316
|
+
if (!config.features.includes("mobile"))
|
|
317
|
+
actions.push("Remove mobile (Capacitor) scaffolding");
|
|
318
|
+
if (config.features.includes("desktop") || config.features.includes("mobile")) {
|
|
319
|
+
actions.push("Flip next.config.ts to output: 'export' (static)");
|
|
320
|
+
}
|
|
321
|
+
if (config.mlServices.length === 0) {
|
|
322
|
+
actions.push("Remove ML playground, router, types");
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
const removed = [
|
|
326
|
+
"background-removal",
|
|
327
|
+
"subtitles",
|
|
328
|
+
"image-recognition",
|
|
329
|
+
"3d-extraction",
|
|
330
|
+
].filter((s) => !config.mlServices.includes(s));
|
|
331
|
+
if (removed.length > 0) {
|
|
332
|
+
actions.push(`Remove unused ML pages: ${removed.join(", ")}`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
for (const action of actions) {
|
|
336
|
+
console.log(chalk.dim(` - ${action}`));
|
|
337
|
+
}
|
|
338
|
+
return actions;
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/scaffold/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ProjectConfig } from "../prompts.js";
|
|
2
|
+
export interface DotenvxValues {
|
|
3
|
+
/** Values to encrypt into .env.production. User-supplied only —
|
|
4
|
+
* empty string / undefined = "I'll fill this in later" (then we
|
|
5
|
+
* write a plaintext CHANGE_ME_<KEY> placeholder instead). */
|
|
6
|
+
[envKey: string]: string | undefined;
|
|
7
|
+
}
|
|
8
|
+
export interface DotenvxSeedResult {
|
|
9
|
+
/** Full DOTENV_PRIVATE_KEY_PRODUCTION (hex). Stored in keychain. */
|
|
10
|
+
privateKey: string;
|
|
11
|
+
/** Corresponding public key — also embedded at the top of
|
|
12
|
+
* `.env.production` by dotenvx. Safe to log / commit. */
|
|
13
|
+
publicKey: string;
|
|
14
|
+
/** Keys that ended up as plaintext CHANGE_ME (user didn't supply). */
|
|
15
|
+
placeholderKeys: string[];
|
|
16
|
+
/** Keys that got encrypted. */
|
|
17
|
+
encryptedKeys: string[];
|
|
18
|
+
}
|
|
19
|
+
/** Populate the starter's `packages/server/.env.production` with
|
|
20
|
+
* encrypted values + a plaintext CHANGE_ME_<KEY> for anything the
|
|
21
|
+
* user didn't supply. Mirrors the generated private key into the
|
|
22
|
+
* macOS Keychain (or equivalent) and returns it so callers can push
|
|
23
|
+
* it to Coolify / print a retrieval hint. */
|
|
24
|
+
export declare function seedDotenvxProduction(outputDir: string, config: ProjectConfig, userValues: DotenvxValues): Promise<DotenvxSeedResult>;
|
|
25
|
+
/** Prompt the user for the subset of candidate keys that are
|
|
26
|
+
* sensitive + likely already known at scaffold time. Anything they
|
|
27
|
+
* leave blank falls through to CHANGE_ME. Skipped entirely in
|
|
28
|
+
* non-interactive mode — presets should carry the values instead. */
|
|
29
|
+
export declare function printDotenvxSummary(result: DotenvxSeedResult, projectName: string): void;
|
|
30
|
+
//# sourceMappingURL=dotenvx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dotenvx.d.ts","sourceRoot":"","sources":["../../src/scaffold/dotenvx.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,MAAM,WAAW,aAAa;IAC5B;;kEAE8D;IAC9D,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB;IAChC,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB;8DAC0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,+BAA+B;IAC/B,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAWD;;;;8CAI8C;AAC9C,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,aAAa,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAiD5B;AAwDD;;;sEAGsE;AACtE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAmBxF"}
|