@ghentcdh/create-crouton 0.0.1-alpha.39 → 0.0.1-alpha.44
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 +361 -30
- package/dist/index.js.map +1 -1
- package/dist/templates/docker/.dockerignore.tmpl +4 -1
- package/dist/templates/docker/.env.infra.example.tmpl +5 -0
- package/dist/templates/docker/.env.infra.tmpl +5 -0
- package/dist/templates/docker/Dockerfile.dev.tmpl +14 -13
- package/dist/templates/docker/Dockerfile.prod.tmpl +107 -17
- package/dist/templates/docker/compose.app.tmpl +53 -0
- package/dist/templates/docker/compose.infra.yml.tmpl +24 -0
- package/dist/templates/docker/compose.yml.tmpl +4 -27
- package/dist/templates/nx/workspace/.env.example.tmpl +2 -0
- package/dist/templates/nx/workspace/.env.tmpl +2 -3
- package/dist/templates/regular/.env.example.tmpl +1 -0
- package/dist/templates/regular/.env.tmpl +1 -0
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -18854,25 +18854,38 @@ var transformDataSource = (data) => {
|
|
|
18854
18854
|
};
|
|
18855
18855
|
var DataSourceSchema = DataSourceShape.transform(transformDataSource);
|
|
18856
18856
|
|
|
18857
|
+
// ../crouton-core/src/lib/data-source/Security.schema.ts
|
|
18858
|
+
var SecuritySchema = external_exports.union([
|
|
18859
|
+
external_exports.object({ public: external_exports.literal(true) }),
|
|
18860
|
+
external_exports.object({ guard: external_exports.union([external_exports.string(), external_exports.array(external_exports.string()).min(1)]) })
|
|
18861
|
+
]);
|
|
18862
|
+
|
|
18857
18863
|
// ../crouton-core/src/lib/data-source/Operations.schema.ts
|
|
18864
|
+
var OpEntry = external_exports.union([
|
|
18865
|
+
external_exports.boolean(),
|
|
18866
|
+
external_exports.object({ security: SecuritySchema.optional() })
|
|
18867
|
+
]);
|
|
18858
18868
|
var BoolOrUpsertSchema = external_exports.union([
|
|
18859
18869
|
external_exports.boolean(),
|
|
18860
|
-
external_exports.object({
|
|
18870
|
+
external_exports.object({
|
|
18871
|
+
upsertOn: external_exports.union([external_exports.string(), external_exports.array(external_exports.string())]),
|
|
18872
|
+
security: SecuritySchema.optional()
|
|
18873
|
+
})
|
|
18861
18874
|
]);
|
|
18862
18875
|
var JsonOperationsSchema = external_exports.object({
|
|
18863
|
-
findAll:
|
|
18876
|
+
findAll: OpEntry.default(true),
|
|
18864
18877
|
// default: true — only explicit `false` disables it
|
|
18865
|
-
findOne:
|
|
18878
|
+
findOne: OpEntry.default(true),
|
|
18866
18879
|
// default: true
|
|
18867
|
-
create:
|
|
18880
|
+
create: OpEntry.default(true),
|
|
18868
18881
|
// default: true
|
|
18869
|
-
update:
|
|
18882
|
+
update: OpEntry.default(true),
|
|
18870
18883
|
// default: true
|
|
18871
|
-
patch:
|
|
18884
|
+
patch: OpEntry.default(true),
|
|
18872
18885
|
// default: true
|
|
18873
18886
|
upsert: BoolOrUpsertSchema.default(false),
|
|
18874
18887
|
// default: disabled; `true` throws at load time — must be `{ upsertOn }`
|
|
18875
|
-
delete:
|
|
18888
|
+
delete: OpEntry.default(true)
|
|
18876
18889
|
// default: true
|
|
18877
18890
|
});
|
|
18878
18891
|
|
|
@@ -19002,6 +19015,57 @@ var CalculatedColumnSchema = external_exports.object({
|
|
|
19002
19015
|
fieldInput: FieldInputSchema.optional()
|
|
19003
19016
|
}).transform(normalizeLabel);
|
|
19004
19017
|
|
|
19018
|
+
// ../crouton-core/src/lib/resource/ColumnType.schema.ts
|
|
19019
|
+
var ColumnTypeShorthandSchema = external_exports.enum([
|
|
19020
|
+
"string",
|
|
19021
|
+
"number",
|
|
19022
|
+
"integer",
|
|
19023
|
+
"boolean",
|
|
19024
|
+
"date",
|
|
19025
|
+
"date-time",
|
|
19026
|
+
"object",
|
|
19027
|
+
"array"
|
|
19028
|
+
]);
|
|
19029
|
+
var JsonSchemaFragmentSchema = external_exports.lazy(
|
|
19030
|
+
() => external_exports.object({
|
|
19031
|
+
type: external_exports.union([external_exports.string(), external_exports.array(external_exports.string())]).optional(),
|
|
19032
|
+
format: external_exports.string().optional(),
|
|
19033
|
+
enum: external_exports.array(external_exports.unknown()).optional(),
|
|
19034
|
+
const: external_exports.unknown().optional(),
|
|
19035
|
+
nullable: external_exports.boolean().optional(),
|
|
19036
|
+
properties: external_exports.record(external_exports.string(), JsonSchemaFragmentSchema).optional(),
|
|
19037
|
+
required: external_exports.array(external_exports.string()).optional(),
|
|
19038
|
+
items: JsonSchemaFragmentSchema.optional(),
|
|
19039
|
+
additionalProperties: external_exports.union([external_exports.boolean(), JsonSchemaFragmentSchema]).optional(),
|
|
19040
|
+
title: external_exports.string().optional(),
|
|
19041
|
+
description: external_exports.string().optional(),
|
|
19042
|
+
default: external_exports.unknown().optional(),
|
|
19043
|
+
minimum: external_exports.number().optional(),
|
|
19044
|
+
maximum: external_exports.number().optional(),
|
|
19045
|
+
minLength: external_exports.number().optional(),
|
|
19046
|
+
maxLength: external_exports.number().optional(),
|
|
19047
|
+
pattern: external_exports.string().optional()
|
|
19048
|
+
}).catchall(external_exports.unknown())
|
|
19049
|
+
);
|
|
19050
|
+
var ColumnTypeSchema = external_exports.union([
|
|
19051
|
+
ColumnTypeShorthandSchema,
|
|
19052
|
+
JsonSchemaFragmentSchema
|
|
19053
|
+
]);
|
|
19054
|
+
var SHORTHAND_FRAGMENTS = {
|
|
19055
|
+
string: { type: "string" },
|
|
19056
|
+
number: { type: "number" },
|
|
19057
|
+
integer: { type: "integer" },
|
|
19058
|
+
boolean: { type: "boolean" },
|
|
19059
|
+
date: { type: "string", format: "date" },
|
|
19060
|
+
"date-time": { type: "string", format: "date-time" },
|
|
19061
|
+
object: { type: "object" },
|
|
19062
|
+
array: { type: "array" }
|
|
19063
|
+
};
|
|
19064
|
+
var NESTED_SHORTHANDS = {
|
|
19065
|
+
date: SHORTHAND_FRAGMENTS.date,
|
|
19066
|
+
"date-time": SHORTHAND_FRAGMENTS["date-time"]
|
|
19067
|
+
};
|
|
19068
|
+
|
|
19005
19069
|
// ../crouton-core/src/lib/resource/Column.ts
|
|
19006
19070
|
var WhenConditionSchema = external_exports.object({
|
|
19007
19071
|
field: external_exports.string(),
|
|
@@ -19056,6 +19120,41 @@ var JsonColumnSchema = external_exports.object({
|
|
|
19056
19120
|
// default: false — exactly one column should set this
|
|
19057
19121
|
showInLookup: external_exports.boolean().default(false),
|
|
19058
19122
|
// default: false
|
|
19123
|
+
/**
|
|
19124
|
+
* Data type of the column, as a shorthand name (`"string"`, `"integer"`, …)
|
|
19125
|
+
* or a full JSON Schema fragment:
|
|
19126
|
+
*
|
|
19127
|
+
* ```json
|
|
19128
|
+
* "type": {
|
|
19129
|
+
* "type": "object",
|
|
19130
|
+
* "properties": { "id": { "type": "string" }, "name": { "type": "string" } }
|
|
19131
|
+
* }
|
|
19132
|
+
* ```
|
|
19133
|
+
*
|
|
19134
|
+
* Required on every column of a `kind: "custom"` resource, where it is the
|
|
19135
|
+
* only source of the resource's json_schema. Optional on a `prisma`
|
|
19136
|
+
* resource, whose schema is derived from the Zod model.
|
|
19137
|
+
*/
|
|
19138
|
+
type: ColumnTypeSchema.optional(),
|
|
19139
|
+
/**
|
|
19140
|
+
* Whether the form requires a value.
|
|
19141
|
+
*
|
|
19142
|
+
* A prisma resource derives `required` from its Zod model, so this is an
|
|
19143
|
+
* override in either direction: `true` adds the column to the form schema's
|
|
19144
|
+
* `required` array, `false` removes it, and omitting it leaves the model's
|
|
19145
|
+
* answer alone. A `kind: "custom"` resource has no model, so this is the only
|
|
19146
|
+
* way to mark one of its fields required.
|
|
19147
|
+
*
|
|
19148
|
+
* Applies to the **form** view only — a required filter input would make the
|
|
19149
|
+
* filter panel unsubmittable, and the table and view schemas are read-only.
|
|
19150
|
+
* Ignored on the id column and on columns that are neither createable nor
|
|
19151
|
+
* updateable, since the form cannot supply a value for those.
|
|
19152
|
+
*/
|
|
19153
|
+
required: external_exports.boolean().optional(),
|
|
19154
|
+
/**
|
|
19155
|
+
* @deprecated Use `type` instead. Retained because it is still consumed by
|
|
19156
|
+
* the boolean predicate and the schema-less sub-resource view builder.
|
|
19157
|
+
*/
|
|
19059
19158
|
columnType: external_exports.string().default("string"),
|
|
19060
19159
|
// default: 'string'
|
|
19061
19160
|
fieldInput: FieldInputSchema.optional(),
|
|
@@ -19092,6 +19191,22 @@ var JsonColumnSchema = external_exports.object({
|
|
|
19092
19191
|
// per-sub-column overrides, only used with `extend`
|
|
19093
19192
|
});
|
|
19094
19193
|
|
|
19194
|
+
// ../crouton-core/src/lib/resource/ParentRef.schema.ts
|
|
19195
|
+
var ParentRefSchema = external_exports.object({
|
|
19196
|
+
/** Route segment of the parent, e.g. `"group"`. */
|
|
19197
|
+
route: external_exports.string(),
|
|
19198
|
+
/**
|
|
19199
|
+
* Name of the path parameter carrying the parent id, e.g. `"groupId"`.
|
|
19200
|
+
* Avoid `"id"` — that is the child's own id in `/:id` routes.
|
|
19201
|
+
*/
|
|
19202
|
+
param: external_exports.string().default("parentId"),
|
|
19203
|
+
/** Type of the parent id, used to coerce the path param. Defaults to `'string'`. */
|
|
19204
|
+
idType: external_exports.enum(["string", "number"]).optional()
|
|
19205
|
+
});
|
|
19206
|
+
|
|
19207
|
+
// ../crouton-core/src/lib/resource/ResourceKind.ts
|
|
19208
|
+
var ResourceKindSchema = external_exports.enum(["prisma", "custom"]).default("prisma");
|
|
19209
|
+
|
|
19095
19210
|
// ../crouton-core/src/lib/resource/Sidebar.schema.ts
|
|
19096
19211
|
var SidebarGroupSchema = zod_default.object({
|
|
19097
19212
|
/** Human-readable heading shown in the sidebar. Defaults to a title-cased version of the slug. */
|
|
@@ -19234,24 +19349,46 @@ var ResourceJsonShape = external_exports.object({
|
|
|
19234
19349
|
schemaVersion: external_exports.number().int().positive().optional(),
|
|
19235
19350
|
/** When `true`, the resource lives in the repo but is NOT loaded/served (work in progress). */
|
|
19236
19351
|
draft: external_exports.boolean().optional().default(false),
|
|
19352
|
+
/**
|
|
19353
|
+
* Where the data comes from. `prisma` (the default) is backed by a Prisma
|
|
19354
|
+
* model plus a `schema.ts`; `custom` is configuration only and the developer
|
|
19355
|
+
* supplies a `repository.ts`. See `./ResourceKind`.
|
|
19356
|
+
*/
|
|
19357
|
+
kind: ResourceKindSchema,
|
|
19237
19358
|
name: external_exports.string(),
|
|
19238
19359
|
// required — unique id, used as the frontend form id
|
|
19239
19360
|
route: external_exports.string(),
|
|
19240
19361
|
// required — URL segment for generated endpoints
|
|
19241
|
-
|
|
19242
|
-
|
|
19362
|
+
/**
|
|
19363
|
+
* Prisma model name. Required when `kind` is `prisma` (enforced by the
|
|
19364
|
+
* refinement on `ResourceJsonSchema`), and must be absent when `kind` is
|
|
19365
|
+
* `custom` — there is no Prisma delegate to address.
|
|
19366
|
+
*/
|
|
19367
|
+
model: external_exports.string().optional(),
|
|
19243
19368
|
tag: external_exports.string(),
|
|
19244
19369
|
// required — OpenAPI tag
|
|
19245
19370
|
title: external_exports.string().optional(),
|
|
19246
19371
|
// no computed default — used as UI display title
|
|
19247
19372
|
table: external_exports.string().optional(),
|
|
19248
19373
|
// default: same as `model`
|
|
19374
|
+
/**
|
|
19375
|
+
* Type of the resource's primary key, used to coerce `:id` route params.
|
|
19376
|
+
* Written by codegen from the Prisma model; defaults to `'string'`.
|
|
19377
|
+
*/
|
|
19378
|
+
idType: external_exports.enum(["string", "number"]).optional(),
|
|
19249
19379
|
database: external_exports.string().optional(),
|
|
19250
19380
|
// default: project's default data source
|
|
19381
|
+
/**
|
|
19382
|
+
* Mount this resource under a parent route instead of at the top level —
|
|
19383
|
+
* see `./ParentRef.schema`. Only valid on a `kind: "custom"` resource.
|
|
19384
|
+
*/
|
|
19385
|
+
parent: ParentRefSchema.optional(),
|
|
19251
19386
|
sidebar: SidebarSchema.default(SidebarSchema.parse({})),
|
|
19252
19387
|
// default: shown, alphabetically ordered, ungrouped
|
|
19253
19388
|
display: JsonDisplaySchema.default(JsonDisplaySchema.parse({})),
|
|
19254
19389
|
// default: { mode: 'modal', customComponent: null }
|
|
19390
|
+
/** Global security block — applies to every operation unless overridden per-operation. */
|
|
19391
|
+
security: SecuritySchema.optional(),
|
|
19255
19392
|
operations: JsonOperationsSchema,
|
|
19256
19393
|
// required key — but every sub-field defaults to enabled
|
|
19257
19394
|
columns: ColumnsSchema.default(ColumnsSchema.parse({})),
|
|
@@ -19272,7 +19409,58 @@ var ResourceJsonShape = external_exports.object({
|
|
|
19272
19409
|
*/
|
|
19273
19410
|
include: external_exports.array(JsonIncludeEntrySchema).default([])
|
|
19274
19411
|
});
|
|
19275
|
-
var
|
|
19412
|
+
var refineByKind = (obj, ctx) => {
|
|
19413
|
+
if (obj.kind === "custom") {
|
|
19414
|
+
if (obj.model !== void 0) {
|
|
19415
|
+
ctx.addIssue({
|
|
19416
|
+
code: "custom",
|
|
19417
|
+
path: ["model"],
|
|
19418
|
+
message: 'A custom resource has no Prisma model. Remove "model" \u2014 data access comes from repository.ts.'
|
|
19419
|
+
});
|
|
19420
|
+
}
|
|
19421
|
+
if (obj.calculatedColumns?.length) {
|
|
19422
|
+
ctx.addIssue({
|
|
19423
|
+
code: "custom",
|
|
19424
|
+
path: ["calculatedColumns"],
|
|
19425
|
+
message: "calculatedColumns run raw SQL against a database table and are not supported on a custom resource. Compute the value in repository.ts instead."
|
|
19426
|
+
});
|
|
19427
|
+
}
|
|
19428
|
+
for (const [id, col] of Object.entries(obj.columns ?? {})) {
|
|
19429
|
+
if (col.fieldInput?.format === "relation" || col.fieldInput?.type === "autocomplete") {
|
|
19430
|
+
continue;
|
|
19431
|
+
}
|
|
19432
|
+
if (col.type === void 0) {
|
|
19433
|
+
ctx.addIssue({
|
|
19434
|
+
code: "custom",
|
|
19435
|
+
path: ["columns", id, "type"],
|
|
19436
|
+
message: `Column "${id}" needs a "type": a custom resource has no schema.ts, so its json_schema is built from the column types.`
|
|
19437
|
+
});
|
|
19438
|
+
}
|
|
19439
|
+
}
|
|
19440
|
+
if (obj.parent && obj.parent.param === "id") {
|
|
19441
|
+
ctx.addIssue({
|
|
19442
|
+
code: "custom",
|
|
19443
|
+
path: ["parent", "param"],
|
|
19444
|
+
message: `parent.param cannot be "id" \u2014 that is the child's own id in /:id routes. Use something like "groupId".`
|
|
19445
|
+
});
|
|
19446
|
+
}
|
|
19447
|
+
} else if (obj.parent !== void 0) {
|
|
19448
|
+
ctx.addIssue({
|
|
19449
|
+
code: "custom",
|
|
19450
|
+
path: ["parent"],
|
|
19451
|
+
message: '"parent" is only supported on a custom resource. A prisma resource is nested by declaring a relation column on its parent.'
|
|
19452
|
+
});
|
|
19453
|
+
} else if (obj.model === void 0) {
|
|
19454
|
+
ctx.addIssue({
|
|
19455
|
+
code: "custom",
|
|
19456
|
+
path: ["model"],
|
|
19457
|
+
message: '"model" is required for a prisma-backed resource. Set "kind": "custom" for a resource with no Prisma model.'
|
|
19458
|
+
});
|
|
19459
|
+
}
|
|
19460
|
+
};
|
|
19461
|
+
var ResourceJsonSchema = ResourceJsonShape.superRefine(
|
|
19462
|
+
refineByKind
|
|
19463
|
+
).transform((obj) => {
|
|
19276
19464
|
const title = obj.title ?? labelFromId(obj.name);
|
|
19277
19465
|
const schemaVersion = obj.schemaVersion ?? BASELINE_RESOURCE_VERSION;
|
|
19278
19466
|
return {
|
|
@@ -19290,7 +19478,7 @@ var RulesetSchema = external_exports.object({
|
|
|
19290
19478
|
hideIdInView: external_exports.boolean().default(true),
|
|
19291
19479
|
hideTimestamps: external_exports.boolean().default(true),
|
|
19292
19480
|
hideForeignKeys: external_exports.boolean().default(true),
|
|
19293
|
-
includeRelations: external_exports.boolean().default(
|
|
19481
|
+
includeRelations: external_exports.boolean().default(true),
|
|
19294
19482
|
hideRelationsInTable: external_exports.boolean().default(true),
|
|
19295
19483
|
showRelationsInForm: external_exports.boolean().default(true),
|
|
19296
19484
|
enumValueLabel: external_exports.boolean().default(true),
|
|
@@ -19299,6 +19487,14 @@ var RulesetSchema = external_exports.object({
|
|
|
19299
19487
|
JsonOperationsSchema.parse({})
|
|
19300
19488
|
)
|
|
19301
19489
|
});
|
|
19490
|
+
var I18nConfigSchema = external_exports.object({
|
|
19491
|
+
/** Default / fallback language. */
|
|
19492
|
+
defaultLanguage: external_exports.string().default("en"),
|
|
19493
|
+
/** All supported language codes. */
|
|
19494
|
+
languages: external_exports.array(external_exports.string()).min(1),
|
|
19495
|
+
/** Directory containing `<lang>.json` bundles, relative to project root. */
|
|
19496
|
+
translationsDir: external_exports.string().default("translations")
|
|
19497
|
+
});
|
|
19302
19498
|
var CroutonConfigSchema = external_exports.object({
|
|
19303
19499
|
/**
|
|
19304
19500
|
* Application title served to the frontend via `GET /_app/layout`.
|
|
@@ -19328,7 +19524,9 @@ var CroutonConfigSchema = external_exports.object({
|
|
|
19328
19524
|
* Whether form fields are saved automatically as the user edits them.
|
|
19329
19525
|
* @default true
|
|
19330
19526
|
*/
|
|
19331
|
-
autoSave: external_exports.boolean().default(true)
|
|
19527
|
+
autoSave: external_exports.boolean().default(true),
|
|
19528
|
+
/** Optional i18n / translation configuration. */
|
|
19529
|
+
i18n: I18nConfigSchema.optional()
|
|
19332
19530
|
});
|
|
19333
19531
|
|
|
19334
19532
|
// ../crouton-core/src/lib/view/view.schema.ts
|
|
@@ -19346,6 +19544,36 @@ var ViewConfigSchema = external_exports.object({
|
|
|
19346
19544
|
defaultSort: external_exports.string().optional()
|
|
19347
19545
|
});
|
|
19348
19546
|
|
|
19547
|
+
// ../crouton-core/src/lib/i18n/Translations.schema.ts
|
|
19548
|
+
var NestedStringRecord = external_exports.lazy(
|
|
19549
|
+
() => external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), NestedStringRecord]))
|
|
19550
|
+
);
|
|
19551
|
+
var TranslationBundleSchema = external_exports.object({
|
|
19552
|
+
app: external_exports.object({
|
|
19553
|
+
title: external_exports.string().optional()
|
|
19554
|
+
}).optional(),
|
|
19555
|
+
sidebarGroups: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
19556
|
+
resources: external_exports.record(
|
|
19557
|
+
external_exports.string(),
|
|
19558
|
+
external_exports.object({
|
|
19559
|
+
title: external_exports.string().optional(),
|
|
19560
|
+
sidebar: external_exports.string().optional(),
|
|
19561
|
+
columns: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
19562
|
+
actions: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
19563
|
+
subResources: external_exports.record(
|
|
19564
|
+
external_exports.string(),
|
|
19565
|
+
external_exports.object({
|
|
19566
|
+
title: external_exports.string().optional(),
|
|
19567
|
+
columns: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
19568
|
+
}).optional()
|
|
19569
|
+
).optional()
|
|
19570
|
+
}).optional()
|
|
19571
|
+
).optional(),
|
|
19572
|
+
enums: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.string())).optional(),
|
|
19573
|
+
ui: NestedStringRecord.optional(),
|
|
19574
|
+
validation: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
19575
|
+
}).passthrough();
|
|
19576
|
+
|
|
19349
19577
|
// ../crouton-codegen/src/util.ts
|
|
19350
19578
|
import { access } from "fs/promises";
|
|
19351
19579
|
|
|
@@ -19603,21 +19831,30 @@ var runCreate = async (name, opts) => {
|
|
|
19603
19831
|
M2.info(`Using pnpm ${pnpmVersion}`);
|
|
19604
19832
|
}
|
|
19605
19833
|
const dbUrl = await resolveDbUrl(opts);
|
|
19834
|
+
const postgres = opts.docker !== false ? await resolvePostgres(opts) : false;
|
|
19606
19835
|
const dbName = name.replace(/[^a-zA-Z0-9]/g, "_");
|
|
19836
|
+
const appName = prefix || name;
|
|
19607
19837
|
const tokens = {
|
|
19608
19838
|
name,
|
|
19609
19839
|
Name: toTitle(name),
|
|
19610
|
-
version: true ? "0.0.1-alpha.
|
|
19840
|
+
version: true ? "0.0.1-alpha.44" : "latest",
|
|
19611
19841
|
year: String((/* @__PURE__ */ new Date()).getFullYear()),
|
|
19612
19842
|
pmRun: pm === "npm" ? "npm run" : pm,
|
|
19613
19843
|
urlEnv: "DATABASE_URL",
|
|
19614
19844
|
dbUrl: dbUrl || `postgresql://crouton:crouton@localhost:5432/${dbName}?schema=public`,
|
|
19615
|
-
dbName
|
|
19845
|
+
dbName,
|
|
19846
|
+
appName,
|
|
19847
|
+
frontendPort: "4200",
|
|
19848
|
+
backendPort: "3000"
|
|
19616
19849
|
};
|
|
19617
19850
|
if (layout === "nx") {
|
|
19618
19851
|
tokens["nx"] = "true";
|
|
19619
|
-
tokens["backendApp"] =
|
|
19620
|
-
tokens["frontendApp"] =
|
|
19852
|
+
tokens["backendApp"] = `${appName}-backend`;
|
|
19853
|
+
tokens["frontendApp"] = `${appName}-frontend`;
|
|
19854
|
+
tokens["workspaceRoot"] = prefix || ".";
|
|
19855
|
+
tokens["dockerfileDev"] = prefix ? `${prefix}/Dockerfile.dev` : "Dockerfile.dev";
|
|
19856
|
+
tokens["envFile"] = prefix ? `${prefix}/.env` : ".env";
|
|
19857
|
+
tokens["generatedGlob"] = prefix ? `${prefix}/generated/default` : "generated/default";
|
|
19621
19858
|
if (prefix) {
|
|
19622
19859
|
tokens["prefix"] = prefix;
|
|
19623
19860
|
tokens["appsRoot"] = `${prefix}/apps`;
|
|
@@ -19633,10 +19870,23 @@ var runCreate = async (name, opts) => {
|
|
|
19633
19870
|
tokens["generatedTypesPath"] = "generated/default/types/src";
|
|
19634
19871
|
tokens["generatedClientPath"] = "generated/default/client";
|
|
19635
19872
|
}
|
|
19873
|
+
} else {
|
|
19874
|
+
tokens["regular"] = "true";
|
|
19875
|
+
tokens["dockerfileDev"] = "Dockerfile.dev";
|
|
19876
|
+
tokens["envFile"] = ".env";
|
|
19636
19877
|
}
|
|
19637
19878
|
if (frontend) {
|
|
19638
19879
|
tokens["frontend"] = "true";
|
|
19639
19880
|
}
|
|
19881
|
+
if (layout === "nx" && frontend) {
|
|
19882
|
+
tokens["nxFrontend"] = "true";
|
|
19883
|
+
}
|
|
19884
|
+
if (layout === "nx" && !frontend) {
|
|
19885
|
+
tokens["nxBackendOnly"] = "true";
|
|
19886
|
+
}
|
|
19887
|
+
if (postgres) {
|
|
19888
|
+
tokens["postgres"] = "true";
|
|
19889
|
+
}
|
|
19640
19890
|
const templateRoot = resolveTemplateDir();
|
|
19641
19891
|
const skipPaths = !frontend ? ["apps/frontend"] : [];
|
|
19642
19892
|
if (layout === "nx") {
|
|
@@ -19659,12 +19909,12 @@ var runCreate = async (name, opts) => {
|
|
|
19659
19909
|
);
|
|
19660
19910
|
files.push(...workspaceFiles);
|
|
19661
19911
|
if (opts.docker !== false) {
|
|
19662
|
-
const
|
|
19663
|
-
|
|
19664
|
-
dockerDir,
|
|
19665
|
-
"",
|
|
19912
|
+
const dockerFiles = await renderDockerTemplates(
|
|
19913
|
+
templateRoot,
|
|
19666
19914
|
tokens,
|
|
19667
|
-
targetDir
|
|
19915
|
+
targetDir,
|
|
19916
|
+
workspaceTarget,
|
|
19917
|
+
{ postgres }
|
|
19668
19918
|
);
|
|
19669
19919
|
files.push(...dockerFiles);
|
|
19670
19920
|
}
|
|
@@ -19701,13 +19951,12 @@ var runCreate = async (name, opts) => {
|
|
|
19701
19951
|
skipPaths
|
|
19702
19952
|
);
|
|
19703
19953
|
if (opts.docker !== false) {
|
|
19704
|
-
const
|
|
19705
|
-
|
|
19706
|
-
|
|
19707
|
-
|
|
19708
|
-
|
|
19709
|
-
|
|
19710
|
-
targetDir
|
|
19954
|
+
const dockerFiles = await renderDockerTemplates(
|
|
19955
|
+
templateRoot,
|
|
19956
|
+
tokens,
|
|
19957
|
+
targetDir,
|
|
19958
|
+
targetDir,
|
|
19959
|
+
{ postgres }
|
|
19711
19960
|
);
|
|
19712
19961
|
files.push(...dockerFiles);
|
|
19713
19962
|
}
|
|
@@ -19736,7 +19985,7 @@ var runCreate = async (name, opts) => {
|
|
|
19736
19985
|
const prefixFlag = prefix ? ` --prefix ${prefix}` : "";
|
|
19737
19986
|
Me(
|
|
19738
19987
|
[
|
|
19739
|
-
opts.docker !== false ? "docker compose up -d # start postgres" : null,
|
|
19988
|
+
opts.docker !== false && postgres ? "docker compose up -d # start postgres" : null,
|
|
19740
19989
|
`${pmRun} prisma:migrate # create initial migration`,
|
|
19741
19990
|
`crouton update resources${prefixFlag} # generate resource CRUD`,
|
|
19742
19991
|
`${pmRun} dev # start dev server`
|
|
@@ -19752,6 +20001,78 @@ var runCreate = async (name, opts) => {
|
|
|
19752
20001
|
throw err;
|
|
19753
20002
|
}
|
|
19754
20003
|
};
|
|
20004
|
+
var renderDockerTemplates = async (templateRoot, tokens, targetDir, workspaceTarget, opts) => {
|
|
20005
|
+
const dockerDir = resolve2(templateRoot, "docker");
|
|
20006
|
+
const files = [];
|
|
20007
|
+
const composeYml = render(
|
|
20008
|
+
await loadTemplate(dockerDir, "compose.yml.tmpl"),
|
|
20009
|
+
tokens
|
|
20010
|
+
);
|
|
20011
|
+
files.push({ path: resolve2(targetDir, "compose.yml"), contents: composeYml });
|
|
20012
|
+
const composeApp = render(
|
|
20013
|
+
await loadTemplate(dockerDir, "compose.app.tmpl"),
|
|
20014
|
+
tokens
|
|
20015
|
+
);
|
|
20016
|
+
files.push({
|
|
20017
|
+
path: resolve2(targetDir, `compose.app.${tokens["appName"]}.yml`),
|
|
20018
|
+
contents: composeApp
|
|
20019
|
+
});
|
|
20020
|
+
if (opts.postgres) {
|
|
20021
|
+
const composeInfra = render(
|
|
20022
|
+
await loadTemplate(dockerDir, "compose.infra.yml.tmpl"),
|
|
20023
|
+
tokens
|
|
20024
|
+
);
|
|
20025
|
+
files.push({
|
|
20026
|
+
path: resolve2(targetDir, "compose.infra.yml"),
|
|
20027
|
+
contents: composeInfra
|
|
20028
|
+
});
|
|
20029
|
+
const envInfra = render(
|
|
20030
|
+
await loadTemplate(dockerDir, ".env.infra.tmpl"),
|
|
20031
|
+
tokens
|
|
20032
|
+
);
|
|
20033
|
+
files.push({
|
|
20034
|
+
path: resolve2(targetDir, ".env.infra"),
|
|
20035
|
+
contents: envInfra
|
|
20036
|
+
});
|
|
20037
|
+
const envInfraExample = render(
|
|
20038
|
+
await loadTemplate(dockerDir, ".env.infra.example.tmpl"),
|
|
20039
|
+
tokens
|
|
20040
|
+
);
|
|
20041
|
+
files.push({
|
|
20042
|
+
path: resolve2(targetDir, ".env.infra.example"),
|
|
20043
|
+
contents: envInfraExample
|
|
20044
|
+
});
|
|
20045
|
+
files.push({
|
|
20046
|
+
path: resolve2(targetDir, "docker/init-data/.gitkeep"),
|
|
20047
|
+
contents: ""
|
|
20048
|
+
});
|
|
20049
|
+
}
|
|
20050
|
+
const dockerfileDev = render(
|
|
20051
|
+
await loadTemplate(dockerDir, "Dockerfile.dev.tmpl"),
|
|
20052
|
+
tokens
|
|
20053
|
+
);
|
|
20054
|
+
files.push({
|
|
20055
|
+
path: resolve2(workspaceTarget, "Dockerfile.dev"),
|
|
20056
|
+
contents: dockerfileDev
|
|
20057
|
+
});
|
|
20058
|
+
const dockerfileProd = render(
|
|
20059
|
+
await loadTemplate(dockerDir, "Dockerfile.prod.tmpl"),
|
|
20060
|
+
tokens
|
|
20061
|
+
);
|
|
20062
|
+
files.push({
|
|
20063
|
+
path: resolve2(workspaceTarget, "Dockerfile.prod"),
|
|
20064
|
+
contents: dockerfileProd
|
|
20065
|
+
});
|
|
20066
|
+
const dockerignore = render(
|
|
20067
|
+
await loadTemplate(dockerDir, ".dockerignore.tmpl"),
|
|
20068
|
+
tokens
|
|
20069
|
+
);
|
|
20070
|
+
files.push({
|
|
20071
|
+
path: resolve2(targetDir, ".dockerignore"),
|
|
20072
|
+
contents: dockerignore
|
|
20073
|
+
});
|
|
20074
|
+
return files;
|
|
20075
|
+
};
|
|
19755
20076
|
var postScaffold = async (opts, targetDir, pm, dbUrl, prefix) => {
|
|
19756
20077
|
if (opts.git !== false) {
|
|
19757
20078
|
const s = Y2();
|
|
@@ -19864,6 +20185,16 @@ var resolveDbUrl = async (opts) => {
|
|
|
19864
20185
|
);
|
|
19865
20186
|
return url2.trim();
|
|
19866
20187
|
};
|
|
20188
|
+
var resolvePostgres = async (opts) => {
|
|
20189
|
+
if (opts.yes) return opts.postgres;
|
|
20190
|
+
if (!opts.postgres) return false;
|
|
20191
|
+
return assertNotCancel(
|
|
20192
|
+
await ye({
|
|
20193
|
+
message: "Run PostgreSQL in Docker?",
|
|
20194
|
+
initialValue: true
|
|
20195
|
+
})
|
|
20196
|
+
);
|
|
20197
|
+
};
|
|
19867
20198
|
var loadAndRenderTemplates = async (templateDir, subPath, tokens, targetDir, skipPaths = []) => {
|
|
19868
20199
|
const files = [];
|
|
19869
20200
|
const dir = subPath ? resolve2(templateDir, subPath) : templateDir;
|
|
@@ -19892,7 +20223,7 @@ var loadAndRenderTemplates = async (templateDir, subPath, tokens, targetDir, ski
|
|
|
19892
20223
|
};
|
|
19893
20224
|
|
|
19894
20225
|
// src/index.ts
|
|
19895
|
-
var program2 = new Command("create-crouton").description("Scaffold a new crouton project").version("0.0.1").argument("[name]", "project name", "my-crouton-app").option("--nx", "use Nx monorepo layout").option("--no-nx", "use regular (non-Nx) layout").option("--no-frontend", "skip frontend app generation").option("--sample", "include sample resource").option("--pm <manager>", "package manager (pnpm | npm | yarn | bun)").option("--no-install", "skip dependency installation").option("--no-git", "skip git init").option("--prefix <name>", "nest apps/config under a subfolder (Nx only)").option("--no-docker", "skip Docker file generation").option("-y, --yes", "accept all defaults (non-interactive)").option("--force", "overwrite existing files").option("--db-url <url>", "database connection URL (e.g. postgresql://user:pass@localhost:5432/db)").action(async (name, opts) => {
|
|
20226
|
+
var program2 = new Command("create-crouton").description("Scaffold a new crouton project").version("0.0.1").argument("[name]", "project name", "my-crouton-app").option("--nx", "use Nx monorepo layout").option("--no-nx", "use regular (non-Nx) layout").option("--no-frontend", "skip frontend app generation").option("--sample", "include sample resource").option("--pm <manager>", "package manager (pnpm | npm | yarn | bun)").option("--no-install", "skip dependency installation").option("--no-git", "skip git init").option("--prefix <name>", "nest apps/config under a subfolder (Nx only)").option("--no-docker", "skip Docker file generation").option("--no-postgres", "skip PostgreSQL in Docker (use external DB)").option("-y, --yes", "accept all defaults (non-interactive)").option("--force", "overwrite existing files").option("--db-url <url>", "database connection URL (e.g. postgresql://user:pass@localhost:5432/db)").action(async (name, opts) => {
|
|
19896
20227
|
try {
|
|
19897
20228
|
await runCreate(name, opts);
|
|
19898
20229
|
} catch (err) {
|