@wneng/create-keel 0.3.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/index.js +206 -13
  2. package/dist/index.js.map +1 -1
  3. package/package.json +1 -1
  4. package/src/templates/ci-gitee/files/pipeline.yml +62 -0
  5. package/src/templates/ci-github/files/ci.yml +160 -0
  6. package/src/templates/db-go-elasticsearch/files/Makefile +18 -0
  7. package/src/templates/db-go-elasticsearch/files/apply_templates.go +80 -0
  8. package/src/templates/db-go-elasticsearch/files/db-README.md +57 -0
  9. package/src/templates/db-go-elasticsearch/files/go.mod +7 -0
  10. package/src/templates/db-go-elasticsearch/files/index-template-init.json +25 -0
  11. package/src/templates/db-go-elasticsearch/fragment.yaml +22 -0
  12. package/src/templates/db-go-migrate-mysql/files/000001_init.down.sql +3 -0
  13. package/src/templates/db-go-migrate-mysql/files/000001_init.up.sql +35 -0
  14. package/src/templates/db-go-migrate-mysql/files/Makefile +33 -0
  15. package/src/templates/db-go-migrate-mysql/files/db-README.md +77 -0
  16. package/src/templates/db-go-migrate-mysql/files/go.mod +8 -0
  17. package/src/templates/db-go-migrate-mysql/fragment.yaml +22 -0
  18. package/src/templates/db-go-migrate-postgres/files/000001_init.down.sql +3 -0
  19. package/src/templates/db-go-migrate-postgres/files/000001_init.up.sql +32 -0
  20. package/src/templates/db-go-migrate-postgres/files/Makefile +31 -0
  21. package/src/templates/db-go-migrate-postgres/files/db-README.md +71 -0
  22. package/src/templates/db-go-migrate-postgres/files/go.mod +8 -0
  23. package/src/templates/db-go-migrate-postgres/fragment.yaml +22 -0
  24. package/src/templates/db-java-elasticsearch/files/EsTemplateApplier.java +86 -0
  25. package/src/templates/db-java-elasticsearch/files/db-README.md +63 -0
  26. package/src/templates/db-java-elasticsearch/files/index-template-init.json +25 -0
  27. package/src/templates/db-java-elasticsearch/files/pom.xml +134 -0
  28. package/src/templates/db-java-elasticsearch/fragment.yaml +19 -0
  29. package/src/templates/db-java-flyway-mysql/files/V1__init.sql +44 -0
  30. package/src/templates/db-java-flyway-mysql/files/application.yaml +39 -0
  31. package/src/templates/db-java-flyway-mysql/files/db-README.md +102 -0
  32. package/src/templates/db-java-flyway-mysql/files/pom.xml +172 -0
  33. package/src/templates/db-java-flyway-mysql/fragment.yaml +19 -0
  34. package/src/templates/db-java-flyway-postgres/files/V1__init.sql +40 -0
  35. package/src/templates/db-java-flyway-postgres/files/application.yaml +37 -0
  36. package/src/templates/db-java-flyway-postgres/files/db-README.md +75 -0
  37. package/src/templates/db-java-flyway-postgres/files/pom.xml +166 -0
  38. package/src/templates/db-java-flyway-postgres/fragment.yaml +19 -0
  39. package/src/templates/db-node-elasticsearch/files/apply-templates.cjs +60 -0
  40. package/src/templates/db-node-elasticsearch/files/db-README.md +76 -0
  41. package/src/templates/db-node-elasticsearch/files/index-template-init.json +26 -0
  42. package/src/templates/db-node-elasticsearch/files/package.json +26 -0
  43. package/src/templates/db-node-elasticsearch/fragment.yaml +19 -0
  44. package/src/templates/db-node-knex-mysql/files/db-README.md +90 -0
  45. package/src/templates/db-node-knex-mysql/files/knexfile.cjs +72 -0
  46. package/src/templates/db-node-knex-mysql/files/migrations-init.cjs +42 -0
  47. package/src/templates/db-node-knex-mysql/files/package.json +31 -0
  48. package/src/templates/db-node-knex-mysql/files/seeds-dev-fixtures.cjs +38 -0
  49. package/src/templates/db-node-knex-mysql/files/seeds-prod-dictionaries.cjs +25 -0
  50. package/src/templates/db-node-knex-mysql/fragment.yaml +25 -0
  51. package/src/templates/db-node-knex-postgres/files/db-README.md +81 -0
  52. package/src/templates/db-node-knex-postgres/files/knexfile.cjs +67 -0
  53. package/src/templates/db-node-knex-postgres/files/migrations-init.cjs +42 -0
  54. package/src/templates/db-node-knex-postgres/files/package.json +31 -0
  55. package/src/templates/db-node-knex-postgres/files/seeds-dev-fixtures.cjs +36 -0
  56. package/src/templates/db-node-knex-postgres/files/seeds-prod-dictionaries.cjs +26 -0
  57. package/src/templates/db-node-knex-postgres/fragment.yaml +25 -0
  58. package/src/templates/db-python-alembic-mysql/files/0001_init.py +70 -0
  59. package/src/templates/db-python-alembic-mysql/files/alembic.ini +47 -0
  60. package/src/templates/db-python-alembic-mysql/files/db-README.md +87 -0
  61. package/src/templates/db-python-alembic-mysql/files/env.py +71 -0
  62. package/src/templates/db-python-alembic-mysql/files/pyproject.toml +52 -0
  63. package/src/templates/db-python-alembic-mysql/files/script.py.mako +26 -0
  64. package/src/templates/db-python-alembic-mysql/fragment.yaml +25 -0
  65. package/src/templates/db-python-alembic-postgres/files/0001_init.py +62 -0
  66. package/src/templates/db-python-alembic-postgres/files/alembic.ini +45 -0
  67. package/src/templates/db-python-alembic-postgres/files/db-README.md +70 -0
  68. package/src/templates/db-python-alembic-postgres/files/env.py +62 -0
  69. package/src/templates/db-python-alembic-postgres/files/pyproject.toml +52 -0
  70. package/src/templates/db-python-alembic-postgres/files/script.py.mako +25 -0
  71. package/src/templates/db-python-alembic-postgres/fragment.yaml +25 -0
  72. package/src/templates/db-python-elasticsearch/files/apply_templates.py +55 -0
  73. package/src/templates/db-python-elasticsearch/files/db-README.md +57 -0
  74. package/src/templates/db-python-elasticsearch/files/index-template-init.json +25 -0
  75. package/src/templates/db-python-elasticsearch/files/pyproject.toml +50 -0
  76. package/src/templates/db-python-elasticsearch/fragment.yaml +19 -0
  77. package/src/templates/docs-skeleton/files/governance-database.md +150 -0
  78. package/src/templates/docs-skeleton/fragment.yaml +3 -0
  79. package/src/templates/root-files/files/AGENTS.md +6 -2
  80. package/src/templates/server-python/files/README.md +75 -2
  81. package/src/templates/server-python/files/app-init.py +11 -1
  82. package/src/templates/server-python/files/config.py +40 -0
  83. package/src/templates/server-python/files/main.py +62 -0
  84. package/src/templates/server-python/files/pyproject.toml +14 -1
  85. package/src/templates/server-python/files/test_healthz.py +36 -0
  86. package/src/templates/server-python/fragment.yaml +10 -1
package/dist/index.js CHANGED
@@ -1,12 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/version.ts
4
- var SCAFFOLDER_VERSION = "0.3.6";
4
+ var SCAFFOLDER_VERSION = "0.4.0";
5
5
 
6
6
  // src/schema/options.ts
7
7
  import Ajv from "ajv";
8
8
  import addFormats from "ajv-formats";
9
9
  import { parse as parseYaml } from "yaml";
10
+
11
+ // src/database/kinds.ts
12
+ var DATABASE_KINDS = ["none", "mysql", "postgres", "elasticsearch"];
13
+ var DATABASE_KIND_LABELS = {
14
+ none: "No database",
15
+ mysql: "MySQL 8 / MariaDB",
16
+ postgres: "PostgreSQL 14+",
17
+ elasticsearch: "Elasticsearch 8"
18
+ };
19
+
20
+ // src/schema/options.ts
10
21
  var BACKEND_LANGUAGES = ["node", "python", "go", "java", "none"];
11
22
  var FRONTEND_FRAMEWORKS = ["react", "vue", "none"];
12
23
  var AGENT_KINDS = ["rust-desktop", "none"];
@@ -35,7 +46,8 @@ var OPTIONS_FIELD_ORDER = [
35
46
  "integrations",
36
47
  "ci",
37
48
  "roles",
38
- "multiApp"
49
+ "multiApp",
50
+ "database"
39
51
  ];
40
52
  var OPTIONS_SCHEMA = {
41
53
  $schema: "http://json-schema.org/draft-07/schema#",
@@ -58,7 +70,8 @@ var OPTIONS_SCHEMA = {
58
70
  "integrations",
59
71
  "ci",
60
72
  "roles",
61
- "multiApp"
73
+ "multiApp",
74
+ "database"
62
75
  ],
63
76
  properties: {
64
77
  projectName: {
@@ -82,7 +95,20 @@ var OPTIONS_SCHEMA = {
82
95
  items: { type: "string", enum: [...ROLE_KINDS] },
83
96
  uniqueItems: true
84
97
  },
85
- multiApp: { type: "boolean" }
98
+ multiApp: { type: "boolean" },
99
+ database: { type: "string", enum: [...DATABASE_KINDS] }
100
+ },
101
+ // Cross-axis constraint: `backend === 'none'` requires `database === 'none'`.
102
+ // A non-'none' database without a backend would be a contradiction (no
103
+ // server to host the migrations / driver). Encoded as if/then so AJV
104
+ // reports a precise error path on violation.
105
+ if: {
106
+ properties: { backend: { const: "none" } },
107
+ required: ["backend"]
108
+ },
109
+ then: {
110
+ properties: { database: { const: "none" } },
111
+ required: ["database"]
86
112
  }
87
113
  };
88
114
  var ajv = new Ajv({ allErrors: true, strict: true });
@@ -425,6 +451,7 @@ function parseCreateArgs(args) {
425
451
  let license;
426
452
  let gitLfs;
427
453
  let integrations;
454
+ let database;
428
455
  function takeEnum(flag, next, enumValues) {
429
456
  if (next === void 0 || next.startsWith("--")) {
430
457
  throw new UserInputError(
@@ -516,6 +543,11 @@ function parseCreateArgs(args) {
516
543
  i += 1;
517
544
  break;
518
545
  }
546
+ case "--database": {
547
+ database = takeEnum("--database", args[i + 1], DATABASE_KINDS);
548
+ i += 1;
549
+ break;
550
+ }
519
551
  case "--engineering-standards": {
520
552
  const next = args[i + 1];
521
553
  if (next === void 0 || next.startsWith("--")) {
@@ -612,6 +644,12 @@ function parseCreateArgs(args) {
612
644
  "\u9879\u76EE\u540D\u5E94\u5339\u914D ^[a-z0-9][a-z0-9-]{0,62}$\uFF0C\u4F8B\u5982\uFF1Amy-app"
613
645
  );
614
646
  }
647
+ if (backend === "none" && database !== void 0 && database !== "none") {
648
+ throw new UserInputError(
649
+ `--database ${database} is incompatible with --backend none`,
650
+ "\u6570\u636E\u5E93\u9700\u8981\u540E\u7AEF\u5BBF\u4E3B\uFF1B\u8BF7\u9009\u62E9\u4E00\u4E2A\u540E\u7AEF\u6216\u5C06 --database \u8BBE\u4E3A none"
651
+ );
652
+ }
615
653
  const flags = {
616
654
  yes,
617
655
  force,
@@ -634,7 +672,8 @@ function parseCreateArgs(args) {
634
672
  ...ai !== void 0 ? { ai } : {},
635
673
  ...license !== void 0 ? { license } : {},
636
674
  ...gitLfs !== void 0 ? { gitLfs } : {},
637
- ...integrations !== void 0 ? { integrations } : {}
675
+ ...integrations !== void 0 ? { integrations } : {},
676
+ ...database !== void 0 ? { database } : {}
638
677
  };
639
678
  if (sampleFeature && dryRun) {
640
679
  throw new UserInputError(
@@ -722,6 +761,7 @@ function helpText() {
722
761
  " --contract <kind> " + CONTRACT_KINDS.join("|"),
723
762
  " --ai <kind> " + AI_TOOLS.join("|"),
724
763
  " --license <kind> " + LICENSE_KINDS.join("|"),
764
+ " --database <kind> " + DATABASE_KINDS.join("|") + " (requires backend != none)",
725
765
  " --gitLfs Enable Git LFS in the generated project",
726
766
  " --integrations Enable docs/06-\u96C6\u6210\u5BF9\u63A5/ at create time",
727
767
  " -h, --help Show this help",
@@ -775,7 +815,8 @@ var OPTION_DEFAULTS = {
775
815
  integrations: false,
776
816
  ci: "gitee",
777
817
  roles: [],
778
- multiApp: false
818
+ multiApp: false,
819
+ database: "none"
779
820
  };
780
821
  function buildDefaultOptions(projectName) {
781
822
  return { projectName, ...OPTION_DEFAULTS };
@@ -811,7 +852,8 @@ var PARTIAL_OPTIONS_SCHEMA = {
811
852
  items: { type: "string", enum: [...ROLE_KINDS] },
812
853
  uniqueItems: true
813
854
  },
814
- multiApp: { type: "boolean" }
855
+ multiApp: { type: "boolean" },
856
+ database: { type: "string", enum: [...DATABASE_KINDS] }
815
857
  }
816
858
  };
817
859
  var ajv2 = new Ajv2({ allErrors: true, strict: true });
@@ -936,6 +978,25 @@ async function promptForOptions(input) {
936
978
  report,
937
979
  "backend"
938
980
  );
981
+ let database;
982
+ if (backend === "none") {
983
+ database = "none";
984
+ report("database", database, true);
985
+ } else if (pre.database !== void 0) {
986
+ database = pre.database;
987
+ report("database", database, false);
988
+ } else {
989
+ const dbChoices = DATABASE_KINDS.map((k) => ({
990
+ value: k,
991
+ name: `${k.padEnd(14)} ${DATABASE_KIND_LABELS[k]}`
992
+ }));
993
+ database = await p.select(
994
+ "\u6570\u636E\u5E93",
995
+ dbChoices,
996
+ OPTION_DEFAULTS.database
997
+ );
998
+ report("database", database, false);
999
+ }
939
1000
  const frontend = await chooseAxis(
940
1001
  p,
941
1002
  pre.frontend,
@@ -1059,7 +1120,8 @@ async function promptForOptions(input) {
1059
1120
  integrations,
1060
1121
  ci,
1061
1122
  roles,
1062
- multiApp: OPTION_DEFAULTS.multiApp
1123
+ multiApp: OPTION_DEFAULTS.multiApp,
1124
+ database
1063
1125
  };
1064
1126
  }
1065
1127
  async function chooseAxis(prompter, prefilled, question, domain, def, report, axisName) {
@@ -1110,7 +1172,8 @@ var APPLIES_WHEN_SCHEMA = {
1110
1172
  gitLfs: { type: "boolean" },
1111
1173
  integrations: { type: "boolean" },
1112
1174
  ci: { type: "string", enum: [...CI_PLATFORMS] },
1113
- role: { type: "string", enum: [...ROLE_KINDS] }
1175
+ role: { type: "string", enum: [...ROLE_KINDS] },
1176
+ database: { type: "string", enum: [...DATABASE_KINDS] }
1114
1177
  }
1115
1178
  };
1116
1179
  var MANIFEST_SCHEMA = {
@@ -1577,6 +1640,12 @@ function collectIssues3() {
1577
1640
  }));
1578
1641
  }
1579
1642
  function assertMetadata(value) {
1643
+ if (value !== null && typeof value === "object" && "options" in value && typeof value.options === "object" && value.options !== null) {
1644
+ const opts = value.options;
1645
+ if (!("database" in opts)) {
1646
+ opts.database = "none";
1647
+ }
1648
+ }
1580
1649
  if (!validateFn3(value)) {
1581
1650
  throw new MetadataValidationError(collectIssues3());
1582
1651
  }
@@ -1877,6 +1946,106 @@ import { accessSync as accessSync2 } from "node:fs";
1877
1946
  import * as path6 from "node:path";
1878
1947
  import { fileURLToPath as fileURLToPath2 } from "node:url";
1879
1948
 
1949
+ // src/database/matrix.ts
1950
+ var MATRIX = Object.freeze({
1951
+ // ---- node -------------------------------------------------------------
1952
+ "node+mysql": {
1953
+ fragmentName: "db-node-knex-mysql",
1954
+ migrationTool: "knex",
1955
+ driverDeps: [
1956
+ { name: "knex", version: "3.1.0" },
1957
+ { name: "mysql2", version: "3.11.3" }
1958
+ ]
1959
+ },
1960
+ "node+postgres": {
1961
+ fragmentName: "db-node-knex-postgres",
1962
+ migrationTool: "knex",
1963
+ driverDeps: [
1964
+ { name: "knex", version: "3.1.0" },
1965
+ { name: "pg", version: "8.13.0" }
1966
+ ]
1967
+ },
1968
+ "node+elasticsearch": {
1969
+ fragmentName: "db-node-elasticsearch",
1970
+ migrationTool: "es-template-applier",
1971
+ driverDeps: [{ name: "@elastic/elasticsearch", version: "8.15.0" }]
1972
+ },
1973
+ // ---- java -------------------------------------------------------------
1974
+ "java+mysql": {
1975
+ fragmentName: "db-java-flyway-mysql",
1976
+ migrationTool: "flyway",
1977
+ driverDeps: [
1978
+ { name: "flyway-core", version: "10.20.0" },
1979
+ { name: "flyway-mysql", version: "10.20.0" },
1980
+ { name: "mysql-connector-j", version: "9.1.0" }
1981
+ ]
1982
+ },
1983
+ "java+postgres": {
1984
+ fragmentName: "db-java-flyway-postgres",
1985
+ migrationTool: "flyway",
1986
+ driverDeps: [
1987
+ { name: "flyway-core", version: "10.20.0" },
1988
+ { name: "flyway-database-postgresql", version: "10.20.0" },
1989
+ { name: "postgresql", version: "42.7.4" }
1990
+ ]
1991
+ },
1992
+ "java+elasticsearch": {
1993
+ fragmentName: "db-java-elasticsearch",
1994
+ migrationTool: "es-template-applier",
1995
+ driverDeps: [{ name: "spring-data-elasticsearch", version: "5.3.5" }]
1996
+ },
1997
+ // ---- python -----------------------------------------------------------
1998
+ "python+mysql": {
1999
+ fragmentName: "db-python-alembic-mysql",
2000
+ migrationTool: "alembic",
2001
+ driverDeps: [
2002
+ { name: "alembic", version: "1.13.3" },
2003
+ { name: "pymysql", version: "1.1.1" }
2004
+ ]
2005
+ },
2006
+ "python+postgres": {
2007
+ fragmentName: "db-python-alembic-postgres",
2008
+ migrationTool: "alembic",
2009
+ driverDeps: [
2010
+ { name: "alembic", version: "1.13.3" },
2011
+ { name: "psycopg", version: "3.2.3" }
2012
+ ]
2013
+ },
2014
+ "python+elasticsearch": {
2015
+ fragmentName: "db-python-elasticsearch",
2016
+ migrationTool: "es-template-applier",
2017
+ driverDeps: [{ name: "elasticsearch", version: "8.15.1" }]
2018
+ },
2019
+ // ---- go ---------------------------------------------------------------
2020
+ "go+mysql": {
2021
+ fragmentName: "db-go-migrate-mysql",
2022
+ migrationTool: "golang-migrate",
2023
+ driverDeps: [
2024
+ { name: "github.com/golang-migrate/migrate/v4", version: "4.18.1" },
2025
+ { name: "github.com/go-sql-driver/mysql", version: "1.8.1" }
2026
+ ]
2027
+ },
2028
+ "go+postgres": {
2029
+ fragmentName: "db-go-migrate-postgres",
2030
+ migrationTool: "golang-migrate",
2031
+ driverDeps: [
2032
+ { name: "github.com/golang-migrate/migrate/v4", version: "4.18.1" },
2033
+ { name: "github.com/jackc/pgx/v5", version: "5.7.1" }
2034
+ ]
2035
+ },
2036
+ "go+elasticsearch": {
2037
+ fragmentName: "db-go-elasticsearch",
2038
+ migrationTool: "es-template-applier",
2039
+ driverDeps: [{ name: "github.com/elastic/go-elasticsearch/v8", version: "8.15.0" }]
2040
+ }
2041
+ });
2042
+ function lookupMatrix(backend, database) {
2043
+ if (database === "none") return null;
2044
+ if (backend === "none") return null;
2045
+ const key = `${backend}+${database}`;
2046
+ return MATRIX[key] ?? null;
2047
+ }
2048
+
1880
2049
  // src/standards/stack-detector.ts
1881
2050
  function backendManifest(opt) {
1882
2051
  switch (opt) {
@@ -1939,8 +2108,10 @@ var SEED_DEPS_GO_SERVER = [
1939
2108
  { name: "github.com/gin-gonic/gin", version: "1.10.0", policy: "minor" }
1940
2109
  ];
1941
2110
  var SEED_DEPS_PYTHON_SERVER = [
1942
- { name: "fastapi", version: "0.111.1", policy: "minor" },
1943
- { name: "pydantic", version: "2.8.2", policy: "minor" }
2111
+ { name: "fastapi", version: "0.115.5", policy: "minor" },
2112
+ { name: "uvicorn", version: "0.32.0", policy: "minor" },
2113
+ { name: "pydantic", version: "2.9.2", policy: "minor" },
2114
+ { name: "pydantic-settings", version: "2.6.1", policy: "minor" }
1944
2115
  ];
1945
2116
  var SEED_DEPS_REACT_WEB = [
1946
2117
  { name: "react", version: "18.3.1", policy: "minor" },
@@ -2028,7 +2199,28 @@ function detectRuntimeManifests(options) {
2028
2199
  miniappManifest(options.miniapp),
2029
2200
  agentManifest(options.agent)
2030
2201
  ];
2031
- return detectors.filter((m) => m !== null).map((m) => ({ ...m, dependencies: seedDeps(options, m.env) }));
2202
+ return detectors.filter((m) => m !== null).map((m) => {
2203
+ const baseDeps = seedDeps(options, m.env);
2204
+ if (m.env === "server") {
2205
+ const matrix = lookupMatrix(options.backend, options.database);
2206
+ if (matrix !== null) {
2207
+ const dbDeps = matrix.driverDeps.map((d) => ({
2208
+ name: d.name,
2209
+ version: d.version,
2210
+ policy: "minor"
2211
+ }));
2212
+ return {
2213
+ ...m,
2214
+ dependencies: [...baseDeps, ...dbDeps],
2215
+ database: {
2216
+ kind: options.database,
2217
+ migrationTool: matrix.migrationTool
2218
+ }
2219
+ };
2220
+ }
2221
+ }
2222
+ return { ...m, dependencies: baseDeps };
2223
+ });
2032
2224
  }
2033
2225
 
2034
2226
  // src/standards/plan.ts
@@ -2338,7 +2530,8 @@ async function resolveOptions(input) {
2338
2530
  ...flags.license !== void 0 ? { license: flags.license } : {},
2339
2531
  ...flags.gitLfs !== void 0 ? { gitLfs: flags.gitLfs } : {},
2340
2532
  ...flags.integrations !== void 0 ? { integrations: flags.integrations } : {},
2341
- ...flags.multiApp !== void 0 ? { multiApp: flags.multiApp } : {}
2533
+ ...flags.multiApp !== void 0 ? { multiApp: flags.multiApp } : {},
2534
+ ...flags.database !== void 0 ? { database: flags.database } : {}
2342
2535
  };
2343
2536
  if (flags.yes) {
2344
2537
  const full = { ...buildDefaultOptions(projectName), ...merged };