@cedarjs/cli 7.0.1-next.467 → 7.1.0-rc.34

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 (194) hide show
  1. package/dist/commands/build/buildHandler.js +1 -2
  2. package/dist/commands/build.js +1 -1
  3. package/dist/commands/check.js +1 -2
  4. package/dist/commands/deploy/baremetal/baremetalHandler.js +73 -364
  5. package/dist/commands/deploy/baremetal.js +1 -7
  6. package/dist/commands/deploy/flightcontrolHandler.js +1 -1
  7. package/dist/commands/deploy/helpers/deployHandler.js +1 -1
  8. package/dist/commands/deploy/netlify.js +1 -1
  9. package/dist/commands/deploy/renderHandler.js +1 -1
  10. package/dist/commands/deploy/serverlessHandler.js +1 -2
  11. package/dist/commands/deploy/vercel.js +1 -1
  12. package/dist/commands/destroy/handlerHelpers.js +1 -1
  13. package/dist/commands/destroy/page/pageHandler.js +1 -2
  14. package/dist/commands/destroy/scaffold/scaffoldHandler.js +26 -65
  15. package/dist/commands/destroy/sdl/sdlHandler.js +1 -2
  16. package/dist/commands/dev/devHandler.js +4 -3
  17. package/dist/commands/dev/packageWatchCommands.js +3 -8
  18. package/dist/commands/dev.js +1 -1
  19. package/dist/commands/execHandler.js +1 -2
  20. package/dist/commands/experimental/live-queries/liveQueries.js +1 -1
  21. package/dist/commands/experimental/live-queries/liveQueriesHandler.js +3 -3
  22. package/dist/commands/experimental/setupInngest.js +1 -1
  23. package/dist/commands/experimental/setupInngestHandler.js +1 -1
  24. package/dist/commands/experimental/setupOpentelemetry.js +1 -1
  25. package/dist/commands/experimental/setupOpentelemetryHandler.js +1 -2
  26. package/dist/commands/experimental/setupReactCompiler.js +1 -1
  27. package/dist/commands/experimental/setupReactCompilerHandler.js +4 -4
  28. package/dist/commands/experimental/setupRsc.js +1 -1
  29. package/dist/commands/experimental/setupRscHandler.js +1 -2
  30. package/dist/commands/experimental/setupStreamingSsr.js +1 -1
  31. package/dist/commands/experimental/setupStreamingSsrHandler.js +2 -3
  32. package/dist/commands/generate/cell/cell.js +0 -20
  33. package/dist/commands/generate/cell/cellHandler.js +20 -68
  34. package/dist/commands/generate/cell/templates/cell.tsx.template +2 -21
  35. package/dist/commands/generate/cell/templates/cellList.tsx.template +2 -21
  36. package/dist/commands/generate/cell/templates/test.js.template +1 -1
  37. package/dist/commands/generate/dataMigration/dataMigration.js +1 -2
  38. package/dist/commands/generate/dbAuth/dbAuth.js +2 -6
  39. package/dist/commands/generate/dbAuth/dbAuthHandler.js +17 -80
  40. package/dist/commands/generate/dbAuth/templates/login.webAuthn.tsx.template +12 -20
  41. package/dist/commands/generate/directive/directiveHandler.js +1 -2
  42. package/dist/commands/generate/function/functionHandler.js +1 -2
  43. package/dist/commands/generate/helpers.js +0 -26
  44. package/dist/commands/generate/job/jobHandler.js +1 -2
  45. package/dist/commands/generate/model/modelHandler.js +1 -2
  46. package/dist/commands/generate/ogImage/ogImageHandler.js +1 -2
  47. package/dist/commands/generate/ogImage/templates/ogImage.og.tsx.template +1 -1
  48. package/dist/commands/generate/package/filesTask.js +12 -9
  49. package/dist/commands/generate/package/packageHandler.js +4 -3
  50. package/dist/commands/generate/package/templates/tsconfig.json.template +0 -1
  51. package/dist/commands/generate/page/pageHandler.js +1 -2
  52. package/dist/commands/generate/realtime/realtime.js +1 -1
  53. package/dist/commands/generate/realtime/realtimeHandler.js +9 -2
  54. package/dist/commands/generate/realtime/templates/liveQueries/blank/blank.service.ts.template +4 -12
  55. package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.service.ts.template +2 -2
  56. package/dist/commands/generate/realtime/templates/subscriptions/blank/blank.ts.template +4 -4
  57. package/dist/commands/generate/scaffold/scaffold.js +1 -1
  58. package/dist/commands/generate/scaffold/scaffoldHandler.js +49 -93
  59. package/dist/commands/generate/scaffold/templates/assets/scaffold.tailwind.css.template +7 -12
  60. package/dist/commands/generate/scaffold/templates/components/EditNameCell.tsx.template +7 -5
  61. package/dist/commands/generate/scaffold/templates/components/NameForm.tsx.template +9 -10
  62. package/dist/commands/generate/scaffold/templates/lib/formatters.test.tsx.template +0 -11
  63. package/dist/commands/generate/scaffold/templates/lib/formatters.tsx.template +4 -16
  64. package/dist/commands/generate/script/scriptHandler.js +1 -2
  65. package/dist/commands/generate/script/templates/tsconfig.json.template +0 -1
  66. package/dist/commands/generate/sdl/sdlHandler.js +4 -10
  67. package/dist/commands/generate/secret/secret.js +1 -1
  68. package/dist/commands/generate/service/serviceHandler.js +49 -79
  69. package/dist/commands/generate/service/templates/service.ts.template +13 -40
  70. package/dist/commands/generate/service/templates/test.ts.template +6 -8
  71. package/dist/commands/generate/yargsCommandHelpers.js +1 -1
  72. package/dist/commands/generate/yargsHandlerHelpers.js +1 -2
  73. package/dist/commands/generate.js +1 -1
  74. package/dist/commands/info.js +1 -1
  75. package/dist/commands/jobsHandler.js +3 -5
  76. package/dist/commands/lint.js +1 -1
  77. package/dist/commands/prerenderHandler.js +4 -11
  78. package/dist/commands/prismaHandler.js +2 -7
  79. package/dist/commands/record/init.js +1 -1
  80. package/dist/commands/serve.js +1 -2
  81. package/dist/commands/setup/auth/auth.js +4 -2
  82. package/dist/commands/setup/cache/cache.js +1 -1
  83. package/dist/commands/setup/cache/cacheHandler.js +1 -2
  84. package/dist/commands/setup/cache/templates/memcached.ts.template +17 -14
  85. package/dist/commands/setup/cache/templates/redis.ts.template +20 -12
  86. package/dist/commands/setup/database/postgres.js +1 -1
  87. package/dist/commands/setup/database/postgresHandler.js +1 -3
  88. package/dist/commands/setup/deploy/providers/baremetal.js +0 -7
  89. package/dist/commands/setup/deploy/providers/baremetalHandler.js +21 -130
  90. package/dist/commands/setup/deploy/providers/coherence.js +1 -1
  91. package/dist/commands/setup/deploy/providers/coherenceHandler.js +6 -7
  92. package/dist/commands/setup/deploy/providers/flightcontrolHandler.js +1 -2
  93. package/dist/commands/setup/deploy/providers/netlifyHandler.js +1 -2
  94. package/dist/commands/setup/deploy/providers/renderHandler.js +1 -2
  95. package/dist/commands/setup/deploy/providers/serverlessHandler.js +1 -2
  96. package/dist/commands/setup/deploy/providers/universalDeployHandler.js +6 -4
  97. package/dist/commands/setup/deploy/providers/vercelHandler.js +1 -2
  98. package/dist/commands/setup/deploy/templates/baremetal.js +9 -119
  99. package/dist/commands/setup/deploy/templates/netlifyUD.js +0 -3
  100. package/dist/commands/setup/docker/docker.js +1 -1
  101. package/dist/commands/setup/docker/dockerHandler.js +1 -2
  102. package/dist/commands/setup/generator/generator.js +1 -1
  103. package/dist/commands/setup/generator/generatorHandler.js +1 -1
  104. package/dist/commands/setup/graphql/features/fragments/fragments.js +1 -1
  105. package/dist/commands/setup/graphql/features/fragments/fragmentsHandler.js +5 -3
  106. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocuments.js +1 -1
  107. package/dist/commands/setup/graphql/features/trustedDocuments/trustedDocumentsHandler.js +1 -2
  108. package/dist/commands/setup/i18n/i18n.js +1 -1
  109. package/dist/commands/setup/i18n/i18nHandler.js +1 -1
  110. package/dist/commands/setup/jobs/jobs.js +1 -1
  111. package/dist/commands/setup/jobs/jobsHandler.js +1 -4
  112. package/dist/commands/setup/mailer/mailer.js +1 -1
  113. package/dist/commands/setup/mailer/mailerHandler.js +1 -2
  114. package/dist/commands/setup/middleware/ogImage/ogImage.js +1 -1
  115. package/dist/commands/setup/middleware/ogImage/ogImageHandler.js +1 -2
  116. package/dist/commands/setup/monitoring/sentry/sentry.js +1 -1
  117. package/dist/commands/setup/monitoring/sentry/sentryHandler.js +9 -13
  118. package/dist/commands/setup/monitoring/sentry/templates/sentryApi.ts.template +4 -1
  119. package/dist/commands/setup/monitoring/sentry/templates/sentryWeb.ts.template +4 -7
  120. package/dist/commands/setup/neon/neon.js +1 -1
  121. package/dist/commands/setup/neon/neonHandler.js +9 -5
  122. package/dist/commands/setup/package/package.js +1 -1
  123. package/dist/commands/setup/package/packageHandler.js +4 -4
  124. package/dist/commands/setup/realtime/addRealtimeToGraphql.js +1 -1
  125. package/dist/commands/setup/realtime/realtime.js +1 -1
  126. package/dist/commands/setup/realtime/realtimeHandler.js +16 -4
  127. package/dist/commands/setup/realtime/templates/defer/fastAndSlowFields/fastAndSlowFields.ts.template +1 -4
  128. package/dist/commands/setup/realtime/templates/liveQueries/auctions/auctions.ts.template +4 -12
  129. package/dist/commands/setup/realtime/templates/subscriptions/countdown/countdown.ts.template +1 -1
  130. package/dist/commands/setup/realtime/templates/subscriptions/newMessage/newMessage.ts.template +2 -2
  131. package/dist/commands/setup/server-file/serverFile.js +1 -1
  132. package/dist/commands/setup/server-file/serverFileHandler.js +1 -2
  133. package/dist/commands/setup/ui/libraries/chakra-uiHandler.js +1 -2
  134. package/dist/commands/setup/ui/libraries/mantineHandler.js +1 -2
  135. package/dist/commands/setup/ui/libraries/tailwindcssHandler.js +82 -63
  136. package/dist/commands/setup/ui/templates/postcss.config.cjs.template +9 -0
  137. package/dist/commands/setup/uploads/dbCodemod.js +28 -0
  138. package/dist/commands/setup/uploads/templates/signedUrl.ts.template +21 -0
  139. package/dist/commands/setup/uploads/templates/srcLibUploads.ts.template +24 -23
  140. package/dist/commands/setup/uploads/uploads.js +7 -49
  141. package/dist/commands/setup/uploads/uploadsHandler.js +69 -277
  142. package/dist/commands/setup.js +1 -2
  143. package/dist/commands/studio.js +1 -1
  144. package/dist/commands/test/testHandler.js +71 -25
  145. package/dist/commands/test/testHandlerEsm.js +109 -0
  146. package/dist/commands/test.js +18 -10
  147. package/dist/commands/testEsm.js +41 -0
  148. package/dist/commands/type-checkHandler.js +1 -1
  149. package/dist/commands/upgrade/preUpgradeScripts.js +3 -3
  150. package/dist/commands/upgrade/upgrade.js +1 -1
  151. package/dist/commands/upgrade/upgradeHandler.js +1 -2
  152. package/dist/index.js +8 -5
  153. package/dist/lib/exit.js +1 -1
  154. package/dist/lib/index.js +31 -16
  155. package/dist/lib/loadEnvFiles.js +1 -1
  156. package/dist/lib/plugin.js +1 -1
  157. package/dist/lib/test.js +1 -1
  158. package/dist/lib/updateCheck.js +4 -4
  159. package/dist/middleware/checkNodeVersion.js +4 -4
  160. package/package.json +27 -27
  161. package/dist/commands/deploy/baremetal/monitors.js +0 -66
  162. package/dist/commands/generate/cell/templates/cellFragment.tsx.template +0 -43
  163. package/dist/commands/generate/cell/templates/storiesFragment.tsx.template +0 -23
  164. package/dist/commands/generate/cell/templates/testFragment.js.template +0 -30
  165. package/dist/commands/generate/dbAuth/templates/changePassword.tsx.template +0 -131
  166. package/dist/commands/generate/dbAuth/templates/login.oauth.tsx.template +0 -164
  167. package/dist/commands/generate/dbAuth/templates/signup.oauth.tsx.template +0 -147
  168. package/dist/commands/generate/scaffold/templates/layouts/NamesScaffoldLayout.tsx.template +0 -18
  169. package/dist/commands/setup/tenancy/authCodemod.js +0 -66
  170. package/dist/commands/setup/tenancy/dbCodemod.js +0 -64
  171. package/dist/commands/setup/tenancy/graphqlCodemod.js +0 -88
  172. package/dist/commands/setup/tenancy/preflight.js +0 -49
  173. package/dist/commands/setup/tenancy/schemaPrisma.js +0 -81
  174. package/dist/commands/setup/tenancy/signupCodemod.js +0 -154
  175. package/dist/commands/setup/tenancy/templates/InvitePage.tsx.template +0 -72
  176. package/dist/commands/setup/tenancy/templates/OrgScope.tsx.template +0 -40
  177. package/dist/commands/setup/tenancy/templates/ensureDefaultOrganizations.dataMigration.ts.template +0 -39
  178. package/dist/commands/setup/tenancy/templates/organizations.scenarios.ts.template +0 -57
  179. package/dist/commands/setup/tenancy/templates/organizations.sdl.ts.template +0 -89
  180. package/dist/commands/setup/tenancy/templates/organizations.test.ts.template +0 -381
  181. package/dist/commands/setup/tenancy/templates/organizations.ts.template +0 -394
  182. package/dist/commands/setup/tenancy/templates/requireMembership.test.ts.template +0 -35
  183. package/dist/commands/setup/tenancy/templates/requireMembership.ts.template +0 -25
  184. package/dist/commands/setup/tenancy/tenancy.js +0 -30
  185. package/dist/commands/setup/tenancy/tenancyHandler.js +0 -425
  186. package/dist/commands/setup/uploads/gitignore.js +0 -17
  187. package/dist/commands/setup/uploads/schemaPrisma.js +0 -41
  188. package/dist/commands/setup/uploads/serverFile.js +0 -217
  189. package/dist/commands/setup/uploads/templates/requireUploadToken.ts.template +0 -15
  190. package/dist/commands/setup/uploads/templates/uploads.sdl.ts.template +0 -79
  191. package/dist/commands/setup/uploads/templates/uploads.ts.template +0 -98
  192. package/dist/commands/setup/uploads/templates/withDataUri.ts.template +0 -14
  193. package/dist/commands/setup/uploads/templates/withSignedUrl.ts.template +0 -16
  194. package/dist/commands/test/viteVersionCheck.js +0 -75
@@ -5,15 +5,14 @@ import { paramCase } from "change-case";
5
5
  import humanize from "humanize-string";
6
6
  import { Listr } from "listr2";
7
7
  import pascalcase from "pascalcase";
8
- import { colors as c } from "@cedarjs/cli-helpers/colors";
8
+ import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
9
9
  import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
10
10
  import {
11
11
  addWorkspacePackages,
12
12
  removeWorkspacePackages
13
13
  } from "@cedarjs/cli-helpers/packageManager/packages";
14
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
15
14
  import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
16
- import { getConfig, getParsedScalars } from "@cedarjs/project-config";
15
+ import { getConfig } from "@cedarjs/project-config";
17
16
  import { pluralize, singularize } from "@cedarjs/utils/cedarPluralize";
18
17
  import {
19
18
  generateTemplate,
@@ -86,18 +85,6 @@ const getImportComponentNames = (name, scaffoldPath, nestScaffoldByModel = true)
86
85
  importLayoutNames: `src/layouts/ScaffoldLayout`
87
86
  };
88
87
  };
89
- const getScaffoldLayoutNames = (name, scaffoldPath = "") => {
90
- const pluralPascalName = pascalcase(pluralize(name));
91
- const directoryName = `${pluralPascalName}ScaffoldLayout`;
92
- const pathParts = scaffoldPath === "" ? [] : scaffoldPath.split("/").map(pascalcase);
93
- return {
94
- directoryName,
95
- pathParts,
96
- // The name to import the layout as in Routes.{jsx,tsx}
97
- importName: pascalcase(scaffoldPath) + directoryName,
98
- importPath: ["src/layouts", ...pathParts, directoryName].join("/")
99
- };
100
- };
101
88
  const getTemplateStrings = (name, scaffoldPath, nestScaffoldByModel = true) => {
102
89
  const nameVars = nameVariants(name);
103
90
  const camelScaffoldPath = camelcase(pascalcase(scaffoldPath));
@@ -109,21 +96,11 @@ const getTemplateStrings = (name, scaffoldPath, nestScaffoldByModel = true) => {
109
96
  ...getImportComponentNames(name, scaffoldPath, nestScaffoldByModel)
110
97
  };
111
98
  };
112
- const webDependsOnTailwindCSS = () => {
113
- const webPackageJsonPath = path.join(getPaths().web.base, "package.json");
114
- if (!fs.existsSync(webPackageJsonPath)) {
115
- return false;
116
- }
117
- const { dependencies, devDependencies } = JSON.parse(
118
- fs.readFileSync(webPackageJsonPath, "utf-8")
119
- );
120
- return Boolean(
121
- dependencies?.["tailwindcss"] || devDependencies?.["tailwindcss"]
122
- );
123
- };
124
99
  const shouldUseTailwindCSS = (flag) => {
125
100
  if (flag === void 0) {
126
- return webDependsOnTailwindCSS();
101
+ return fs.existsSync(
102
+ path.join(getPaths().web.config, "tailwind.config.cjs")
103
+ );
127
104
  } else {
128
105
  return flag;
129
106
  }
@@ -172,13 +149,7 @@ const files = async ({
172
149
  }),
173
150
  ...await assetFiles(name, tailwind),
174
151
  ...await formatters(name, typescript),
175
- ...await layoutFiles(
176
- name,
177
- scaffoldPath,
178
- force,
179
- typescript,
180
- templateStrings
181
- ),
152
+ ...await layoutFiles(name, force, typescript, templateStrings),
182
153
  ...await pageFiles(
183
154
  name,
184
155
  pascalScaffoldPath,
@@ -218,7 +189,6 @@ const assetFiles = async (name, tailwind) => {
218
189
  }
219
190
  return fileList;
220
191
  };
221
- const isDateTimeParsed = () => getParsedScalars().DateTime === "Date";
222
192
  const formatters = async (name, isTypescript) => {
223
193
  const outputPath = path.join(
224
194
  getPaths().web.src,
@@ -240,8 +210,7 @@ const formatters = async (name, isTypescript) => {
240
210
  templatePath: path.join("lib", "formatters.tsx.template")
241
211
  }),
242
212
  {
243
- name,
244
- parsedDateTime: isDateTimeParsed()
213
+ name
245
214
  }
246
215
  );
247
216
  const templateTest = await generateTemplate(
@@ -251,8 +220,7 @@ const formatters = async (name, isTypescript) => {
251
220
  templatePath: path.join("lib", "formatters.test.tsx.template")
252
221
  }),
253
222
  {
254
- name,
255
- parsedDateTime: isDateTimeParsed()
223
+ name
256
224
  }
257
225
  );
258
226
  return {
@@ -372,61 +340,44 @@ const modelRelatedVariables = (model) => {
372
340
  fieldsToImport,
373
341
  editableColumns,
374
342
  listFormattersImports,
375
- formattersImports,
376
- parsedDateTime: isDateTimeParsed()
343
+ formattersImports
377
344
  };
378
345
  };
379
- const layoutFiles = async (name, scaffoldPath, force, generateTypescript, templateStrings) => {
346
+ const layoutFiles = async (name, force, generateTypescript, templateStrings) => {
380
347
  const fileList = {};
381
- const extension = generateTypescript ? ".tsx" : ".jsx";
382
- const renderLayout = async (templateName, outputPath) => {
383
- const template = await generateTemplate(
384
- customOrDefaultTemplatePath({
385
- side: "web",
386
- generator: "scaffold",
387
- templatePath: path.join("layouts", templateName)
388
- }),
389
- {
390
- name,
391
- pascalScaffoldPath: "",
392
- ...templateStrings
393
- }
394
- );
395
- fileList[outputPath] = generateTypescript || !outputPath.endsWith(".jsx") ? template : await transformTSToJS(outputPath, template);
396
- };
397
- const sharedLayoutDir = path.join(getPaths().web.layouts, "ScaffoldLayout");
398
- const sharedLayoutTemplates = fs.readdirSync(
348
+ const layouts = fs.readdirSync(
399
349
  customOrDefaultTemplatePath({
400
350
  side: "web",
401
351
  generator: "scaffold",
402
352
  templatePath: "layouts"
403
353
  })
404
- ).filter((template) => template !== "NamesScaffoldLayout.tsx.template");
405
- for (const template of sharedLayoutTemplates) {
406
- const isComponent = template.endsWith(".tsx.template");
407
- const outputName = isComponent ? template.replace(/\.tsx\.template$/, extension) : template.replace(/\.template$/, "");
408
- const exists = isComponent ? [".tsx", ".jsx", ".ts", ".js"].some(
409
- (ext) => fs.existsSync(
410
- path.join(sharedLayoutDir, outputName.replace(extension, ext))
411
- )
412
- ) : fs.existsSync(path.join(sharedLayoutDir, outputName));
413
- if (!exists || force) {
414
- await renderLayout(template, path.join(sharedLayoutDir, outputName));
415
- }
416
- }
417
- const { directoryName, pathParts } = getScaffoldLayoutNames(
418
- name,
419
- scaffoldPath
420
354
  );
421
- await renderLayout(
422
- "NamesScaffoldLayout.tsx.template",
423
- path.join(
355
+ for (const layout of layouts) {
356
+ const outputLayoutName = layout.replace(
357
+ /\.tsx\.template/,
358
+ generateTypescript ? ".tsx" : ".jsx"
359
+ );
360
+ const outputPath = path.join(
424
361
  getPaths().web.layouts,
425
- ...pathParts,
426
- directoryName,
427
- directoryName + extension
428
- )
429
- );
362
+ "ScaffoldLayout",
363
+ outputLayoutName
364
+ );
365
+ if (!fs.existsSync(outputPath) || force) {
366
+ const template = await generateTemplate(
367
+ customOrDefaultTemplatePath({
368
+ side: "web",
369
+ generator: "scaffold",
370
+ templatePath: path.join("layouts", layout)
371
+ }),
372
+ {
373
+ name,
374
+ pascalScaffoldPath: "",
375
+ ...templateStrings
376
+ }
377
+ );
378
+ fileList[outputPath] = generateTypescript ? template : await transformTSToJS(outputPath, template);
379
+ }
380
+ }
430
381
  return fileList;
431
382
  };
432
383
  const pageFiles = async (name, pascalScaffoldPath = "", generateTypescript, nestScaffoldByModel = true, templateStrings) => {
@@ -468,7 +419,7 @@ const pageFiles = async (name, pascalScaffoldPath = "", generateTypescript, nest
468
419
  ...modelRelatedVariables(model)
469
420
  }
470
421
  );
471
- fileList[outputPath] = generateTypescript || !outputPath.endsWith(".jsx") ? template : await transformTSToJS(outputPath, template);
422
+ fileList[outputPath] = generateTypescript ? template : await transformTSToJS(outputPath, template);
472
423
  }
473
424
  return fileList;
474
425
  };
@@ -516,7 +467,7 @@ const componentFiles = async (name, pascalScaffoldPath = "", generateTypescript,
516
467
  ...modelRelatedVariables(model)
517
468
  }
518
469
  );
519
- fileList[outputPath] = generateTypescript || !outputPath.endsWith(".jsx") ? template : await transformTSToJS(outputPath, template);
470
+ fileList[outputPath] = generateTypescript ? template : await transformTSToJS(outputPath, template);
520
471
  }
521
472
  return fileList;
522
473
  };
@@ -547,9 +498,8 @@ const routes = async ({
547
498
  `<Route path="/${paramScaffoldPath}${nameVars.pluralParamName}" page={${pageRoot}${nameVars.pluralPascalName}Page} name="${templateNames.pluralRouteName}" />`
548
499
  ];
549
500
  };
550
- const addLayoutImport = (model, scaffoldPath) => {
551
- const { importName, importPath } = getScaffoldLayoutNames(model, scaffoldPath);
552
- const importLayout = `import ${importName} from '${importPath}'`;
501
+ const addLayoutImport = () => {
502
+ const importLayout = `import ScaffoldLayout from 'src/layouts/ScaffoldLayout'`;
553
503
  const routesPath = getPaths().web.routes;
554
504
  const routesContent = readFile(routesPath).toString();
555
505
  if (!routesContent.match(importLayout)) {
@@ -663,10 +613,17 @@ const addSetImport = (task) => {
663
613
  return `Added ${namesToImport.join(", ")} import to Routes.{jsx,tsx}`;
664
614
  };
665
615
  const addScaffoldSetToRouter = async (model, scaffoldPath) => {
616
+ const templateNames = getTemplateStrings(model, scaffoldPath);
617
+ const nameVars = nameVariants(model);
618
+ const title = nameVars.pluralPascalName;
619
+ const titleTo = templateNames.pluralRouteName;
620
+ const buttonLabel = `New ${nameVars.singularPascalName}`;
621
+ const buttonTo = templateNames.newRouteName;
666
622
  const unauthenticatedRoute = getUnauthenticatedRedirectRoute();
667
623
  return addRoutesToRouterTask(
668
624
  await routes({ model, path: scaffoldPath }),
669
- getScaffoldLayoutNames(model, scaffoldPath).importName,
625
+ "ScaffoldLayout",
626
+ { title, titleTo, buttonLabel, buttonTo },
670
627
  unauthenticatedRoute ? { unauthenticated: unauthenticatedRoute } : void 0
671
628
  );
672
629
  };
@@ -707,7 +664,7 @@ const tasks = ({
707
664
  },
708
665
  {
709
666
  title: "Adding layout import...",
710
- task: async () => addLayoutImport(model, path2)
667
+ task: async () => addLayoutImport()
711
668
  },
712
669
  {
713
670
  title: "Adding set import...",
@@ -823,7 +780,6 @@ const splitPathAndModel = (pathSlashModel) => {
823
780
  };
824
781
  export {
825
782
  files,
826
- getScaffoldLayoutNames,
827
783
  getUnauthenticatedRedirectRoute,
828
784
  handler,
829
785
  hasLoginRoute,
@@ -1,9 +1,3 @@
1
- /**
2
- * Makes your app's Tailwind theme and utilities available to `@apply`
3
- * without emitting any of the styles in index.css a second time
4
- */
5
- @reference './index.css';
6
-
7
1
  .rw-scaffold {
8
2
  @apply bg-white text-gray-600;
9
3
  }
@@ -33,7 +27,8 @@
33
27
  @apply mx-4 pb-4;
34
28
  }
35
29
  .rw-segment {
36
- @apply rounded-lg overflow-hidden w-full border border-gray-200 scrollbar-thumb-zinc-400 scrollbar-track-transparent;
30
+ @apply rounded-lg overflow-hidden w-full border border-gray-200;
31
+ scrollbar-color: theme('colors.zinc.400') transparent;
37
32
  }
38
33
  .rw-segment::-webkit-scrollbar {
39
34
  height: initial;
@@ -85,7 +80,7 @@
85
80
  }
86
81
  .rw-cell-error,
87
82
  .rw-form-error-wrapper {
88
- @apply p-4 bg-red-50 text-red-600 border border-red-100 rounded-sm my-4;
83
+ @apply p-4 bg-red-50 text-red-600 border border-red-100 rounded my-4;
89
84
  }
90
85
  .rw-form-error-title {
91
86
  @apply m-0 font-semibold;
@@ -94,13 +89,13 @@
94
89
  @apply mt-2 list-disc list-inside;
95
90
  }
96
91
  .rw-button {
97
- @apply flex justify-center py-1 px-4 border-0 rounded-sm bg-gray-200 text-gray-500 text-xs font-semibold uppercase tracking-wide leading-loose no-underline cursor-pointer transition duration-100;
92
+ @apply flex justify-center py-1 px-4 border-0 rounded bg-gray-200 text-gray-500 text-xs font-semibold uppercase tracking-wide leading-loose no-underline cursor-pointer transition duration-100;
98
93
  }
99
94
  .rw-button:hover {
100
95
  @apply bg-gray-500 text-white;
101
96
  }
102
97
  .rw-button.rw-button-small {
103
- @apply text-xs rounded-xs py-1 px-2;
98
+ @apply text-xs rounded-sm py-1 px-2;
104
99
  }
105
100
  .rw-button.rw-button-green {
106
101
  @apply bg-green-500 text-white;
@@ -139,7 +134,7 @@
139
134
  @apply text-red-600;
140
135
  }
141
136
  .rw-input {
142
- @apply block mt-2 w-full p-2 bg-white border border-gray-200 rounded-sm outline-hidden;
137
+ @apply block mt-2 w-full p-2 bg-white border border-gray-200 rounded outline-none;
143
138
  }
144
139
  .rw-check-radio-items {
145
140
  @apply flex justify-items-center;
@@ -158,7 +153,7 @@
158
153
  @apply border-red-600 text-red-600;
159
154
  }
160
155
  .rw-input-error:focus {
161
- @apply border-red-600 outline-hidden;
156
+ @apply border-red-600 outline-none;
162
157
  box-shadow: 0 0 5px #c53030;
163
158
  }
164
159
  .rw-field-error {
@@ -1,7 +1,6 @@
1
1
  ${useClientDirective}import type {
2
2
  Edit${singularPascalName}By${pascalIdName},
3
3
  Update${singularPascalName}Input,
4
- Update${singularPascalName}Mutation,
5
4
  Update${singularPascalName}MutationVariables
6
5
  } from 'types/graphql'
7
6
 
@@ -25,7 +24,7 @@ export const QUERY: TypedDocumentNode<Edit${singularPascalName}By${pascalIdName}
25
24
  `
26
25
 
27
26
  const UPDATE_${singularConstantName}_MUTATION: TypedDocumentNode<
28
- Update${singularPascalName}Mutation,
27
+ Edit${singularPascalName}ById,
29
28
  Update${singularPascalName}MutationVariables
30
29
  > = gql`
31
30
  mutation Update${singularPascalName}Mutation($${idName}: ${idType}!, $input: Update${singularPascalName}Input!) {
@@ -57,14 +56,17 @@ export const Success = ({ ${singularCamelName} }: CellSuccessProps<Edit${singula
57
56
  }
58
57
  )
59
58
 
60
- const onSave = (input: Update${singularPascalName}Input) => {
61
- update${singularPascalName}({ variables: { ${idName}: ${singularCamelName}.${idName}, input } })
59
+ const onSave = (
60
+ input: Update${singularPascalName}Input,
61
+ id: Edit${singularPascalName}By${pascalIdName}['${singularCamelName}']['id']
62
+ ) => {
63
+ update${singularPascalName}({ variables: { id, input } })
62
64
  }
63
65
 
64
66
  return (
65
67
  <div className="rw-segment">
66
68
  <header className="rw-segment-header">
67
- <h2 className="rw-heading rw-heading-secondary">Edit ${singularPascalName} {${singularCamelName}.${idName}}</h2>
69
+ <h2 className="rw-heading rw-heading-secondary">Edit ${singularPascalName} {${singularCamelName}?.id}</h2>
68
70
  </header>
69
71
  <div className="rw-segment-main">
70
72
  <${singularPascalName}Form ${singularCamelName}={${singularCamelName}} onSave={onSave} error={error} loading={loading} />
@@ -1,4 +1,4 @@
1
- import type { Edit${singularPascalName}By${pascalIdName}, Create${singularPascalName}Input } from 'types/graphql'
1
+ import type { Edit${singularPascalName}By${pascalIdName}, Update${singularPascalName}Input } from 'types/graphql'
2
2
 
3
3
  import type { RWGqlError } from '@cedarjs/forms'
4
4
  import {
@@ -12,17 +12,17 @@ import {
12
12
 
13
13
  <% if (fieldsToImport.includes('DatetimeLocalField')) { %>
14
14
  /**
15
- * Formats a DateTime <%= parsedDateTime ? 'Date object' : 'string' %> from the API, which is a UTC timestamp, for use as
15
+ * Formats a DateTime string from the API, which is a UTC timestamp, for use as
16
16
  * the value of a `datetime-local` input. The input takes `YYYY-MM-DDTHH:mm` in
17
17
  * the user's local time, with no seconds, milliseconds or timezone, and the
18
18
  * form reads its value back as local time when it is submitted.
19
19
  */
20
- function formatDatetime(value: <%= parsedDateTime ? 'Date' : 'string' %> | undefined | null) {
20
+ function formatDatetime(value: string | undefined | null) {
21
21
  if (!value) {
22
22
  return undefined
23
23
  }
24
24
 
25
- const date = <%= parsedDateTime ? 'value' : 'new Date(value)' %>
25
+ const date = new Date(value)
26
26
 
27
27
  if (Number.isNaN(date.getTime())) {
28
28
  return undefined
@@ -48,8 +48,8 @@ type Form${singularPascalName} = NonNullable<Edit${singularPascalName}By${pascal
48
48
 
49
49
  interface ${singularPascalName}FormProps {
50
50
  ${singularCamelName}?: Edit${singularPascalName}By${pascalIdName}['${singularCamelName}']
51
- onSave: (data: Create${singularPascalName}Input) => void
52
- error?: RWGqlError
51
+ onSave: (data: Update${singularPascalName}Input, ${idName}?: Form${singularPascalName}['${idName}']) => void
52
+ error: RWGqlError
53
53
  loading: boolean
54
54
  }
55
55
 
@@ -70,8 +70,7 @@ const ${singularPascalName}Form = (props: ${singularPascalName}FormProps) => {
70
70
  }
71
71
  <% } %>
72
72
  <% if (column.isEnum && !column.isList && !column.isRequired) { %>
73
- // The "None" option has an empty value
74
- if (!data.${column.name}) {
73
+ if (data.${column.name} === '') {
75
74
  data.${column.name} = null
76
75
  }
77
76
  <% } %>
@@ -81,7 +80,7 @@ const ${singularPascalName}Form = (props: ${singularPascalName}FormProps) => {
81
80
  }
82
81
  <% } %>
83
82
  <% }) %>
84
- props.onSave(data)
83
+ props.onSave(data, props?.${singularCamelName}?.${idName})
85
84
  }
86
85
 
87
86
  return (
@@ -137,7 +136,7 @@ const ${singularPascalName}Form = (props: ${singularPascalName}FormProps) => {
137
136
  <% } else { %>
138
137
  <${column.component}
139
138
  name="${column.name}"
140
- ${column.defaultProp}={${column.deserializeFunction && column.deserializeFunction + '('}props.${singularCamelName}?.<%= column.name %>${column.deserializeFunction && ')'}<%= !column.deserializeFunction && !column.isRequired ? ' ?? undefined' : '' %>}
139
+ ${column.defaultProp}={${column.deserializeFunction && column.deserializeFunction + '('}props.${singularCamelName}?.<%= column.name %>${column.deserializeFunction && ')'}}
141
140
  className="rw-input"
142
141
  errorClassName="rw-input rw-input-error"
143
142
  <%= !column.validation ? '' : `validation=${column.validation}` %>
@@ -83,25 +83,14 @@ describe('jsonTruncate', () => {
83
83
 
84
84
  describe('timeTag', () => {
85
85
  it('renders a date', async () => {
86
- <% if (parsedDateTime) { %>
87
- render(<div>{timeTag(new Date('1970-08-20'))}</div>)
88
- <% } else { %>
89
86
  render(<div>{timeTag(new Date('1970-08-20').toUTCString())}</div>)
90
- <% } %>
91
87
 
92
88
  await waitFor(() => screen.getByText(/1970.*00:00:00/))
93
89
  })
94
90
 
95
- <% if (parsedDateTime) { %>
96
- it('can take an empty input', async () => {
97
- expect(timeTag(null)).toEqual('')
98
- expect(timeTag(undefined)).toEqual('')
99
- })
100
- <% } else { %>
101
91
  it('can take an empty input string', async () => {
102
92
  expect(timeTag('')).toEqual('')
103
93
  })
104
- <% } %>
105
94
  })
106
95
 
107
96
  describe('jsonDisplay', () => {
@@ -25,7 +25,7 @@ export const jsonDisplay = (obj: unknown) => {
25
25
  )
26
26
  }
27
27
 
28
- export const truncate = (value: string | number | null | undefined) => {
28
+ export const truncate = (value: string | number) => {
29
29
  let output = value?.toString() ?? ''
30
30
 
31
31
  if (output.length > MAX_STRING_LENGTH) {
@@ -39,32 +39,20 @@ export const jsonTruncate = (obj: unknown) => {
39
39
  return truncate(JSON.stringify(obj, null, 2))
40
40
  }
41
41
 
42
- export function timeTag(dateTime: <%= parsedDateTime ? 'Date' : 'string' %> | undefined | null) {
42
+ export function timeTag(dateTime: string | undefined | null) {
43
43
  let output: string | React.JSX.Element = ''
44
44
 
45
45
  if (dateTime) {
46
- <% if (parsedDateTime) { %>
47
- if (!Number.isNaN(dateTime.getTime())) {
48
- const isoString = dateTime.toISOString()
49
-
50
- output = (
51
- <time dateTime={isoString} title={isoString}>
52
- {dateTime.toUTCString()}
53
- </time>
54
- )
55
- }
56
- <% } else { %>
57
46
  output = (
58
47
  <time dateTime={dateTime} title={dateTime}>
59
48
  {new Date(dateTime).toUTCString()}
60
49
  </time>
61
50
  )
62
- <% } %>
63
51
  }
64
52
 
65
53
  return output
66
54
  }
67
55
 
68
- export const checkboxInputTag = (checked: boolean | null | undefined) => {
69
- return <input type="checkbox" checked={!!checked} disabled />
56
+ export const checkboxInputTag = (checked: boolean) => {
57
+ return <input type="checkbox" checked={checked} disabled />
70
58
  }
@@ -1,8 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { Listr } from "listr2";
4
- import { colors as c } from "@cedarjs/cli-helpers/colors";
5
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
4
+ import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
6
5
  import { errorTelemetry } from "@cedarjs/telemetry";
7
6
  import {
8
7
  getPaths,
@@ -2,7 +2,6 @@
2
2
  "compilerOptions": {
3
3
  "noEmit": true,
4
4
  "allowJs": true,
5
- "strict": true,
6
5
  "esModuleInterop": true,
7
6
  "baseUrl": "./",
8
7
  "rootDirs": [
@@ -2,9 +2,8 @@ import ansis from "ansis";
2
2
  import boxen from "boxen";
3
3
  import camelcase from "camelcase";
4
4
  import { Listr } from "listr2";
5
- import { colors as c } from "@cedarjs/cli-helpers/colors";
5
+ import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
6
6
  import { formatCedarCommand } from "@cedarjs/cli-helpers/packageManager/display";
7
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
8
7
  import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
9
8
  import { getConfig } from "@cedarjs/project-config";
10
9
  import { errorTelemetry } from "@cedarjs/telemetry";
@@ -19,11 +18,7 @@ import {
19
18
  getEnum,
20
19
  verifyModelName
21
20
  } from "../../../lib/schemaHelpers.js";
22
- import {
23
- DEFAULT_IGNORE_FIELDS_FOR_INPUT,
24
- redactedModelFields,
25
- relationsForModel
26
- } from "../helpers.js";
21
+ import { redactedModelFields, relationsForModel } from "../helpers.js";
27
22
  import { files as serviceFiles } from "../service/serviceHandler.js";
28
23
  import { templateForFile } from "../yargsHandlerHelpers.js";
29
24
  import {
@@ -31,6 +26,7 @@ import {
31
26
  missingRelatedModels,
32
27
  writeFilesWithStubsTask
33
28
  } from "./stubFiles.js";
29
+ const DEFAULT_IGNORE_FIELDS_FOR_INPUT = ["createdAt", "updatedAt"];
34
30
  const missingIdConsoleMessage = () => {
35
31
  const line1 = ansis.bold.yellow("WARNING") + ": Cannot generate CRUD SDL without an `@id` database column.";
36
32
  const line2 = "If you are trying to generate for a many-to-many join table ";
@@ -64,8 +60,7 @@ const modelFieldToSDL = ({
64
60
  Bytes: "Byte"
65
61
  };
66
62
  const gqlType = prismaTypeToGraphqlType[field.type] || field.type;
67
- const listItemType = field.kind === "object" ? gqlType : `${gqlType}!`;
68
- const type = field.isList ? `[${listItemType}]` : gqlType;
63
+ const type = field.isList ? `[${gqlType}]` : gqlType;
69
64
  const isRequired = field.isRequired && required || field.isList || field.isId;
70
65
  const fieldContent = `${field.name}: ${type}${isRequired ? "!" : ""}`;
71
66
  if (docs) {
@@ -336,7 +331,6 @@ const handler = async ({
336
331
  export {
337
332
  files,
338
333
  handler,
339
- modelFieldToSDL,
340
334
  printRedactedFieldsNote,
341
335
  redactedSensitiveFields,
342
336
  stubFiles
@@ -1,6 +1,6 @@
1
1
  import crypto from "node:crypto";
2
2
  import { terminalLink } from "termi-link";
3
- import { recordTelemetryAttributes } from "@cedarjs/cli-helpers/telemetry";
3
+ import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
4
4
  const DEFAULT_LENGTH = 32;
5
5
  const generateSecret = (length = DEFAULT_LENGTH) => {
6
6
  return crypto.randomBytes(Math.trunc(length)).toString("base64");