tailar 0.4.0 → 0.5.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 +5 -2
- package/README.npm.md +5 -2
- package/dist/api/client.d.ts +22 -28
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +111 -236
- package/dist/api/client.js.map +1 -1
- package/dist/api/errors.d.ts +16 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +32 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/auth/flow.js +1 -1
- package/dist/auth/flow.js.map +1 -1
- package/dist/commands/add.d.ts +9 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +63 -113
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +106 -70
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +1 -23
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/playground.d.ts.map +1 -1
- package/dist/commands/playground.js +2 -1
- package/dist/commands/playground.js.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +9 -4
- package/dist/commands/sync.js.map +1 -1
- package/dist/installers/agent-files.d.ts +26 -0
- package/dist/installers/agent-files.d.ts.map +1 -0
- package/dist/installers/agent-files.js +110 -0
- package/dist/installers/agent-files.js.map +1 -0
- package/dist/installers/dependencies.d.ts +10 -0
- package/dist/installers/dependencies.d.ts.map +1 -1
- package/dist/installers/dependencies.js +52 -8
- package/dist/installers/dependencies.js.map +1 -1
- package/dist/installers/files.d.ts +2 -6
- package/dist/installers/files.d.ts.map +1 -1
- package/dist/installers/files.js +30 -35
- package/dist/installers/files.js.map +1 -1
- package/dist/installers/install-feature.d.ts +25 -1
- package/dist/installers/install-feature.d.ts.map +1 -1
- package/dist/installers/install-feature.js +100 -59
- package/dist/installers/install-feature.js.map +1 -1
- package/dist/installers/managed-blocks.d.ts +26 -0
- package/dist/installers/managed-blocks.d.ts.map +1 -0
- package/dist/installers/managed-blocks.js +47 -0
- package/dist/installers/managed-blocks.js.map +1 -0
- package/dist/installers/post-install.d.ts +12 -0
- package/dist/installers/post-install.d.ts.map +1 -1
- package/dist/installers/post-install.js +19 -0
- package/dist/installers/post-install.js.map +1 -1
- package/dist/installers/setup-guide.d.ts +38 -0
- package/dist/installers/setup-guide.d.ts.map +1 -0
- package/dist/installers/setup-guide.js +206 -0
- package/dist/installers/setup-guide.js.map +1 -0
- package/dist/installers/variant-switch.d.ts +34 -0
- package/dist/installers/variant-switch.d.ts.map +1 -0
- package/dist/installers/variant-switch.js +139 -0
- package/dist/installers/variant-switch.js.map +1 -0
- package/dist/installers/when.d.ts +22 -0
- package/dist/installers/when.d.ts.map +1 -0
- package/dist/installers/when.js +35 -0
- package/dist/installers/when.js.map +1 -0
- package/dist/registry/query.d.ts +6 -1
- package/dist/registry/query.d.ts.map +1 -1
- package/dist/registry/query.js +22 -0
- package/dist/registry/query.js.map +1 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/registry.d.ts +65 -6
- package/dist/types/registry.d.ts.map +1 -1
- package/dist/types/wizard.d.ts +34 -8
- package/dist/types/wizard.d.ts.map +1 -1
- package/dist/types/wizard.js +74 -40
- package/dist/types/wizard.js.map +1 -1
- package/dist/utils/clack-wizard.d.ts +3 -1
- package/dist/utils/clack-wizard.d.ts.map +1 -1
- package/dist/utils/clack-wizard.js +205 -107
- package/dist/utils/clack-wizard.js.map +1 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +12 -5
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/init-flags.d.ts +43 -8
- package/dist/utils/init-flags.d.ts.map +1 -1
- package/dist/utils/init-flags.js +119 -32
- package/dist/utils/init-flags.js.map +1 -1
- package/dist/utils/local-options.js +1 -1
- package/dist/utils/local-options.js.map +1 -1
- package/dist/utils/next-steps.d.ts +9 -0
- package/dist/utils/next-steps.d.ts.map +1 -0
- package/dist/utils/next-steps.js +15 -0
- package/dist/utils/next-steps.js.map +1 -0
- package/dist/utils/presets.d.ts +34 -0
- package/dist/utils/presets.d.ts.map +1 -0
- package/dist/utils/presets.js +82 -0
- package/dist/utils/presets.js.map +1 -0
- package/dist/utils/recipe-id.d.ts +19 -0
- package/dist/utils/recipe-id.d.ts.map +1 -0
- package/dist/utils/recipe-id.js +72 -0
- package/dist/utils/recipe-id.js.map +1 -0
- package/dist/utils/recipe.d.ts +49 -0
- package/dist/utils/recipe.d.ts.map +1 -0
- package/dist/utils/recipe.js +227 -0
- package/dist/utils/recipe.js.map +1 -0
- package/package.json +7 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config ids
|
|
3
|
+
*
|
|
4
|
+
* The id from tailar.dev/build, e.g. `saas-ai-10hhc`, is the configuration itself: the
|
|
5
|
+
* preset (readable) and a short code for the module choices. Nothing is downloaded.
|
|
6
|
+
*
|
|
7
|
+
* The table and the code format are the same as the website's
|
|
8
|
+
* (web/lib/recipes/codec.ts); both test suites share the sample ids. APPEND-ONLY:
|
|
9
|
+
* never reorder or remove an entry. A change that cannot be appended becomes version "2".
|
|
10
|
+
*/
|
|
11
|
+
import type { RecipeConfig } from "./recipe.js";
|
|
12
|
+
/** `<preset>-<5 chars>`, e.g. `saas-ai-10hhc` (same pattern as the website). */
|
|
13
|
+
export declare const RECIPE_ID_PATTERN: RegExp;
|
|
14
|
+
/**
|
|
15
|
+
* The configuration an id stands for. Throws with a message for the user when the id is
|
|
16
|
+
* malformed, mistyped or from a newer CLI. The preset is checked later, against the registry.
|
|
17
|
+
*/
|
|
18
|
+
export declare function decodeRecipeId(id: string): RecipeConfig;
|
|
19
|
+
//# sourceMappingURL=recipe-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe-id.d.ts","sourceRoot":"","sources":["../../src/utils/recipe-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAsBhD,gFAAgF;AAChF,eAAO,MAAM,iBAAiB,QAA0C,CAAC;AAUzE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAwCvD"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config ids
|
|
3
|
+
*
|
|
4
|
+
* The id from tailar.dev/build, e.g. `saas-ai-10hhc`, is the configuration itself: the
|
|
5
|
+
* preset (readable) and a short code for the module choices. Nothing is downloaded.
|
|
6
|
+
*
|
|
7
|
+
* The table and the code format are the same as the website's
|
|
8
|
+
* (web/lib/recipes/codec.ts); both test suites share the sample ids. APPEND-ONLY:
|
|
9
|
+
* never reorder or remove an entry. A change that cannot be appended becomes version "2".
|
|
10
|
+
*/
|
|
11
|
+
const VERSION = "1";
|
|
12
|
+
/** One position per module, in install order: 0 = off, 1.. = the value at that position. */
|
|
13
|
+
const TABLE_V1 = [
|
|
14
|
+
{ module: "database", providerKey: "database", values: ["postgres", "mysql", "mongodb"] },
|
|
15
|
+
{ module: "email", providerKey: "email", values: ["resend", "postmark", "sendgrid"] },
|
|
16
|
+
{ module: "auth", providerKey: "authStructure", values: ["user-based", "org-based"] },
|
|
17
|
+
{ module: "payments", providerKey: "payments", values: ["stripe", "lemonsqueezy", "paddle"] },
|
|
18
|
+
{ module: "storage", providerKey: "storage", values: ["r2", "s3", "gcs"] },
|
|
19
|
+
{ module: "ai", providerKey: null, values: ["on"] },
|
|
20
|
+
];
|
|
21
|
+
const BASE = 36;
|
|
22
|
+
const SIZE = TABLE_V1.reduce((n, entry) => n * (entry.values.length + 1), 1);
|
|
23
|
+
const ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
24
|
+
/** `<preset>-<5 chars>`, e.g. `saas-ai-10hhc` (same pattern as the website). */
|
|
25
|
+
export const RECIPE_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,39}-[0-9a-z]{5}$/;
|
|
26
|
+
function checkChar(text) {
|
|
27
|
+
let sum = 0;
|
|
28
|
+
for (let i = 0; i < text.length; i++) {
|
|
29
|
+
sum += (i + 1) * ALPHABET.indexOf(text[i]);
|
|
30
|
+
}
|
|
31
|
+
return ALPHABET[sum % BASE];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The configuration an id stands for. Throws with a message for the user when the id is
|
|
35
|
+
* malformed, mistyped or from a newer CLI. The preset is checked later, against the registry.
|
|
36
|
+
*/
|
|
37
|
+
export function decodeRecipeId(id) {
|
|
38
|
+
if (!RECIPE_ID_PATTERN.test(id)) {
|
|
39
|
+
throw new Error(`"${id}" is not a config id. Ids look like saas-ai-10hhc (copy yours from tailar.dev/build).`);
|
|
40
|
+
}
|
|
41
|
+
const cut = id.lastIndexOf("-");
|
|
42
|
+
const preset = id.slice(0, cut);
|
|
43
|
+
const body = id.slice(cut + 1, -1);
|
|
44
|
+
if (body[0] !== VERSION) {
|
|
45
|
+
throw new Error(`Config id "${id}" comes from a newer version of Tailar. Update the CLI: npx tailar@latest.`);
|
|
46
|
+
}
|
|
47
|
+
if (checkChar(body) !== id.at(-1)) {
|
|
48
|
+
throw new Error(`Config id "${id}" looks mistyped (its check character does not match). Copy it again from tailar.dev/build.`);
|
|
49
|
+
}
|
|
50
|
+
let value = parseInt(body.slice(1), BASE);
|
|
51
|
+
if (!Number.isInteger(value) || value >= SIZE) {
|
|
52
|
+
throw new Error(`Config id "${id}" is not valid. Copy it again from tailar.dev/build.`);
|
|
53
|
+
}
|
|
54
|
+
const modules = [];
|
|
55
|
+
const providers = {};
|
|
56
|
+
const digits = [];
|
|
57
|
+
for (const entry of [...TABLE_V1].reverse()) {
|
|
58
|
+
const radix = entry.values.length + 1;
|
|
59
|
+
digits.unshift(value % radix);
|
|
60
|
+
value = Math.floor(value / radix);
|
|
61
|
+
}
|
|
62
|
+
TABLE_V1.forEach((entry, i) => {
|
|
63
|
+
const digit = digits[i];
|
|
64
|
+
if (digit === 0)
|
|
65
|
+
return;
|
|
66
|
+
modules.push(entry.module);
|
|
67
|
+
if (entry.providerKey)
|
|
68
|
+
providers[entry.providerKey] = entry.values[digit - 1];
|
|
69
|
+
});
|
|
70
|
+
return { preset, modules, providers };
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=recipe-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe-id.js","sourceRoot":"","sources":["../../src/utils/recipe-id.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recipes
|
|
3
|
+
*
|
|
4
|
+
* A recipe is the configuration a builder id stands for (see recipe-id.ts):
|
|
5
|
+
* { preset, modules, providers, items?, projectName? }. It is turned into the
|
|
6
|
+
* same TailarInitWizardState the `--preset/--modules/...` flags produce, after
|
|
7
|
+
* checking every part of it against the registry in use.
|
|
8
|
+
*/
|
|
9
|
+
import { type InitFlagContext, type InitFlagResult } from "./init-flags.js";
|
|
10
|
+
export interface RecipeConfig {
|
|
11
|
+
preset: string;
|
|
12
|
+
modules: string[];
|
|
13
|
+
providers: Record<string, string>;
|
|
14
|
+
items?: string[];
|
|
15
|
+
projectName?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface LoadedRecipe {
|
|
18
|
+
/** Known when the recipe came from the API, or from a file shaped like the API answer. */
|
|
19
|
+
id?: string;
|
|
20
|
+
config: RecipeConfig;
|
|
21
|
+
}
|
|
22
|
+
/** What a recipe is checked against: the registry flag context plus every registry entry name (for `items`). */
|
|
23
|
+
export interface RecipeContext extends InitFlagContext {
|
|
24
|
+
entries?: string[];
|
|
25
|
+
}
|
|
26
|
+
/** A recipe that cannot be used; `problems` lists everything wrong with it. */
|
|
27
|
+
export declare class RecipeError extends Error {
|
|
28
|
+
readonly problems: string[];
|
|
29
|
+
constructor(label: string, problems: string[]);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Read a recipe from parsed JSON: either the API answer `{ id, config }` or a
|
|
33
|
+
* bare config. Checks the shape only; the registry checks come later.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseRecipeJson(raw: unknown, label?: string): LoadedRecipe;
|
|
36
|
+
/** Read `--recipe-file`. */
|
|
37
|
+
export declare function readRecipeFile(path: string): LoadedRecipe;
|
|
38
|
+
/**
|
|
39
|
+
* Turn a recipe into the wizard state the flags would build, or throw a
|
|
40
|
+
* RecipeError listing everything that does not fit the registry in use
|
|
41
|
+
* (unknown preset, unknown or unavailable modules, invalid providers, unknown
|
|
42
|
+
* items). `projectName` is the explicit choice (argument or --name); without
|
|
43
|
+
* it the recipe's own name, then "my-app".
|
|
44
|
+
*/
|
|
45
|
+
export declare function buildWizardStateFromRecipe(recipe: LoadedRecipe, options?: {
|
|
46
|
+
projectName?: string;
|
|
47
|
+
context?: RecipeContext;
|
|
48
|
+
}): InitFlagResult;
|
|
49
|
+
//# sourceMappingURL=recipe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe.d.ts","sourceRoot":"","sources":["../../src/utils/recipe.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,iBAAiB,CAAC;AAKzB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,0FAA0F;IAC1F,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,gHAAgH;AAChH,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,+EAA+E;AAC/E,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;gBAEhB,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;CAO9C;AAUD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,SAAW,GAAG,YAAY,CA4C5E;AAED,4BAA4B;AAC5B,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAkBzD;AAoCD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,aAAa,CAAA;CAAO,GAC9D,cAAc,CAkHhB"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recipes
|
|
3
|
+
*
|
|
4
|
+
* A recipe is the configuration a builder id stands for (see recipe-id.ts):
|
|
5
|
+
* { preset, modules, providers, items?, projectName? }. It is turned into the
|
|
6
|
+
* same TailarInitWizardState the `--preset/--modules/...` flags produce, after
|
|
7
|
+
* checking every part of it against the registry in use.
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync } from "fs";
|
|
10
|
+
import { MODULE_FEATURES, MODULE_ORDER, normalizeModuleSelection, } from "../types/wizard.js";
|
|
11
|
+
import { BUILTIN_PRESETS, missingRequirements, } from "./presets.js";
|
|
12
|
+
import { DATABASE_PROVIDERS, EMAIL_PROVIDERS, buildWizardStateFromFlags, parseAuthStructure, } from "./init-flags.js";
|
|
13
|
+
/** A directory name that cannot leave the current directory. */
|
|
14
|
+
const SAFE_PROJECT_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
15
|
+
/** A recipe that cannot be used; `problems` lists everything wrong with it. */
|
|
16
|
+
export class RecipeError extends Error {
|
|
17
|
+
problems;
|
|
18
|
+
constructor(label, problems) {
|
|
19
|
+
super(`${label} cannot be used:\n${problems.map((p) => ` - ${p}`).join("\n")}`);
|
|
20
|
+
this.name = "RecipeError";
|
|
21
|
+
this.problems = problems;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function isRecord(value) {
|
|
25
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26
|
+
}
|
|
27
|
+
function isStringArray(value) {
|
|
28
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Read a recipe from parsed JSON: either the API answer `{ id, config }` or a
|
|
32
|
+
* bare config. Checks the shape only; the registry checks come later.
|
|
33
|
+
*/
|
|
34
|
+
export function parseRecipeJson(raw, label = "recipe") {
|
|
35
|
+
if (!isRecord(raw)) {
|
|
36
|
+
throw new RecipeError(label, ["it is not a JSON object"]);
|
|
37
|
+
}
|
|
38
|
+
const wrapped = isRecord(raw.config);
|
|
39
|
+
const id = wrapped && typeof raw.id === "string" ? raw.id : undefined;
|
|
40
|
+
const config = (wrapped ? raw.config : raw);
|
|
41
|
+
const problems = [];
|
|
42
|
+
if (typeof config.preset !== "string" || !config.preset) {
|
|
43
|
+
problems.push('"preset" is missing (a string such as "saas-ai")');
|
|
44
|
+
}
|
|
45
|
+
if (config.modules !== undefined && !isStringArray(config.modules)) {
|
|
46
|
+
problems.push('"modules" must be an array of module ids');
|
|
47
|
+
}
|
|
48
|
+
if (config.providers !== undefined && !isRecord(config.providers)) {
|
|
49
|
+
problems.push('"providers" must be an object');
|
|
50
|
+
}
|
|
51
|
+
if (config.items !== undefined && !isStringArray(config.items)) {
|
|
52
|
+
problems.push('"items" must be an array of registry entry names');
|
|
53
|
+
}
|
|
54
|
+
if (config.projectName !== undefined && typeof config.projectName !== "string") {
|
|
55
|
+
problems.push('"projectName" must be a string');
|
|
56
|
+
}
|
|
57
|
+
if (problems.length > 0)
|
|
58
|
+
throw new RecipeError(label, problems);
|
|
59
|
+
const providers = {};
|
|
60
|
+
for (const [key, value] of Object.entries(config.providers ?? {})) {
|
|
61
|
+
// Extra keys are tolerated; a known key keeps its value so it can be rejected precisely.
|
|
62
|
+
providers[key] = typeof value === "string" ? value : JSON.stringify(value);
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
id,
|
|
66
|
+
config: {
|
|
67
|
+
preset: config.preset,
|
|
68
|
+
modules: config.modules ?? [],
|
|
69
|
+
providers,
|
|
70
|
+
...(config.items ? { items: config.items } : {}),
|
|
71
|
+
...(config.projectName ? { projectName: config.projectName } : {}),
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Read `--recipe-file`. */
|
|
76
|
+
export function readRecipeFile(path) {
|
|
77
|
+
let text;
|
|
78
|
+
try {
|
|
79
|
+
text = readFileSync(path, "utf-8");
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
throw new Error(`Cannot read recipe file ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
83
|
+
}
|
|
84
|
+
let json;
|
|
85
|
+
try {
|
|
86
|
+
json = JSON.parse(text);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
throw new Error(`Recipe file ${path} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
90
|
+
}
|
|
91
|
+
return parseRecipeJson(json, `Recipe file ${path}`);
|
|
92
|
+
}
|
|
93
|
+
function describe(id) {
|
|
94
|
+
return id ? `Recipe "${id}"` : "Recipe";
|
|
95
|
+
}
|
|
96
|
+
/** Providers named in a recipe, by key, with the module each belongs to and the values the registry allows. */
|
|
97
|
+
function providerRules(context) {
|
|
98
|
+
return [
|
|
99
|
+
{
|
|
100
|
+
key: "database",
|
|
101
|
+
module: "database",
|
|
102
|
+
label: "database",
|
|
103
|
+
allowed: context.databaseProviders ?? [...DATABASE_PROVIDERS],
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
key: "email",
|
|
107
|
+
module: "email",
|
|
108
|
+
label: "email",
|
|
109
|
+
allowed: context.emailProviders ?? [...EMAIL_PROVIDERS],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
key: "payments",
|
|
113
|
+
module: "payments",
|
|
114
|
+
label: "payments",
|
|
115
|
+
allowed: context.billingProviders ?? ["stripe"],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
key: "storage",
|
|
119
|
+
module: "storage",
|
|
120
|
+
label: "storage",
|
|
121
|
+
allowed: context.storageProviders ?? ["r2"],
|
|
122
|
+
},
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Turn a recipe into the wizard state the flags would build, or throw a
|
|
127
|
+
* RecipeError listing everything that does not fit the registry in use
|
|
128
|
+
* (unknown preset, unknown or unavailable modules, invalid providers, unknown
|
|
129
|
+
* items). `projectName` is the explicit choice (argument or --name); without
|
|
130
|
+
* it the recipe's own name, then "my-app".
|
|
131
|
+
*/
|
|
132
|
+
export function buildWizardStateFromRecipe(recipe, options = {}) {
|
|
133
|
+
const { config } = recipe;
|
|
134
|
+
const context = options.context ?? {};
|
|
135
|
+
const presets = context.presets ?? BUILTIN_PRESETS;
|
|
136
|
+
const label = describe(recipe.id);
|
|
137
|
+
const problems = [];
|
|
138
|
+
// Preset
|
|
139
|
+
const preset = presets.find((p) => p.id === config.preset);
|
|
140
|
+
if (!preset) {
|
|
141
|
+
problems.push(`unknown preset "${config.preset}" (this registry has: ${presets.map((p) => p.id).join(", ")})`);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
const missing = missingRequirements(preset, context.features);
|
|
145
|
+
if (missing.length > 0) {
|
|
146
|
+
problems.push(`preset "${preset.id}" is not available yet: ${missing.join(", ")} ${missing.length > 1 ? "are" : "is"} not in the registry`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Modules
|
|
150
|
+
const requested = [];
|
|
151
|
+
for (const id of new Set(config.modules.map((m) => m.trim()).filter(Boolean))) {
|
|
152
|
+
if (MODULE_ORDER.includes(id)) {
|
|
153
|
+
requested.push(id);
|
|
154
|
+
}
|
|
155
|
+
else if (id === "analytics") {
|
|
156
|
+
problems.push('module "analytics" is not available yet');
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
problems.push(`unknown module "${id}" (modules: ${MODULE_ORDER.join(", ")})`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const { modules } = normalizeModuleSelection(requested);
|
|
163
|
+
if (context.features) {
|
|
164
|
+
for (const module of modules) {
|
|
165
|
+
if (!context.features.includes(MODULE_FEATURES[module])) {
|
|
166
|
+
problems.push(`module "${module}" is not available yet: ${MODULE_FEATURES[module]} is not in the registry`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Providers: strict on values, tolerant of extra keys
|
|
171
|
+
for (const rule of providerRules(context)) {
|
|
172
|
+
const value = config.providers[rule.key];
|
|
173
|
+
if (value === undefined)
|
|
174
|
+
continue;
|
|
175
|
+
if (!rule.allowed.includes(value)) {
|
|
176
|
+
problems.push(`invalid ${rule.label} provider "${value}" (use ${rule.allowed.join(", ")})`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const structure = config.providers.authStructure;
|
|
180
|
+
if (structure !== undefined) {
|
|
181
|
+
try {
|
|
182
|
+
parseAuthStructure(structure);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
problems.push(`invalid auth structure "${structure}" (use user-based or organization-based)`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Items
|
|
189
|
+
for (const item of config.items ?? []) {
|
|
190
|
+
if (context.entries && !context.entries.includes(item)) {
|
|
191
|
+
problems.push(`unknown item "${item}" (not in the registry)`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Project name taken from the recipe must be a plain directory name
|
|
195
|
+
const recipeName = config.projectName?.trim();
|
|
196
|
+
if (!options.projectName && recipeName && !SAFE_PROJECT_NAME.test(recipeName)) {
|
|
197
|
+
problems.push(`projectName "${recipeName}" is not a plain directory name (letters, digits, dot, dash, underscore)`);
|
|
198
|
+
}
|
|
199
|
+
if (problems.length > 0)
|
|
200
|
+
throw new RecipeError(label, problems);
|
|
201
|
+
const selected = new Set(modules);
|
|
202
|
+
const providers = config.providers;
|
|
203
|
+
let result;
|
|
204
|
+
try {
|
|
205
|
+
result = buildWizardStateFromFlags({
|
|
206
|
+
projectName: options.projectName || recipeName,
|
|
207
|
+
preset: config.preset,
|
|
208
|
+
modules: requested.join(","),
|
|
209
|
+
db: selected.has("database") ? providers.database : undefined,
|
|
210
|
+
email: selected.has("email") ? providers.email : undefined,
|
|
211
|
+
auth: selected.has("auth") ? providers.authStructure : undefined,
|
|
212
|
+
storageProvider: selected.has("storage") ? providers.storage : undefined,
|
|
213
|
+
billingProvider: selected.has("payments") ? providers.payments : undefined,
|
|
214
|
+
}, context);
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
throw new RecipeError(label, [
|
|
218
|
+
error instanceof Error ? error.message : String(error),
|
|
219
|
+
]);
|
|
220
|
+
}
|
|
221
|
+
const state = {
|
|
222
|
+
...result.state,
|
|
223
|
+
...(config.items ? { items: config.items } : {}),
|
|
224
|
+
};
|
|
225
|
+
return { state, autoNotes: result.autoNotes };
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=recipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe.js","sourceRoot":"","sources":["../../src/utils/recipe.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CLI tool for scaffolding Next.js features and components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
|
|
21
21
|
"test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
|
|
22
22
|
"test:install": "node scripts/install-smoke.mjs",
|
|
23
|
+
"test:preset": "node scripts/preset-smoke.mjs",
|
|
23
24
|
"prepublishOnly": "npm run build",
|
|
24
25
|
"prepare-release": "npm run build && cp README.npm.md README.md",
|
|
25
26
|
"version": "node -e \"console.log(require('./package.json').version)\""
|
|
@@ -33,6 +34,11 @@
|
|
|
33
34
|
],
|
|
34
35
|
"author": "Tailar",
|
|
35
36
|
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/tailar-dev/tailar-all.git",
|
|
40
|
+
"directory": "tailar"
|
|
41
|
+
},
|
|
36
42
|
"dependencies": {
|
|
37
43
|
"@clack/prompts": "^0.7.0",
|
|
38
44
|
"chalk": "^5.3.0",
|