Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"@babel/cli": "7.28.3",
"@babel/core": "^7.26.10",
"@types/archiver": "^6",
"@types/pluralize": "0.0.33",
"memfs": "4.51.1",
"node-ssh": "13.2.1",
"tsx": "4.21.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import pascalcase from 'pascalcase'

import { recordTelemetryAttributes } from '@cedarjs/cli-helpers'

import { pluralize } from '../../../lib/cedarPluralize.js'
import c from '../../../lib/colors.js'
import {
deleteFilesTask,
Expand All @@ -11,7 +12,6 @@ import {
removeRoutesFromRouterTask,
writeFile,
} from '../../../lib/index.js'
import { pluralize } from '../../../lib/rwPluralize.js'
import { verifyModelName } from '../../../lib/schemaHelpers.js'
import {
files,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/generate/cell/cellHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import pascalcase from 'pascalcase'

import { generate as generateTypes } from '@cedarjs/internal/dist/generate/generate'

import { isPlural, singularize } from '../../../lib/cedarPluralize.js'
import { nameVariants, transformTSToJS } from '../../../lib/index.js'
import { isWordPluralizable } from '../../../lib/pluralHelpers.js'
import { addFunctionToRollback } from '../../../lib/rollback.js'
import { isPlural, singularize } from '../../../lib/rwPluralize.js'
import { getSchema } from '../../../lib/schemaHelpers.js'
import { forcePluralizeWord, removeGeneratorName } from '../helpers.js'
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
// CWD, plus importing this file statically also makes the CLI startup time
// much slower

import type { DMMF } from '@prisma/generator-helper'
import { paramCase } from 'change-case'
import pascalcase from 'pascalcase'

import { pluralize, isPlural, isSingular } from '../../lib/rwPluralize.js'
import { pluralize, isPlural, isSingular } from '../../lib/cedarPluralize.js'

/**
* Creates a route path, either returning the existing path if passed, or
* creating one based on the name. If the passed path is just a route parameter
* a new path based on the name is created, with the parameter appended to it
*/
export const pathName = (path, name) => {
export const pathName = (path: string | undefined, name: string) => {
let routePath = path

if (path && path.startsWith('{') && path.endsWith('}')) {
Expand All @@ -30,8 +31,7 @@ export const pathName = (path, name) => {
return routePath
}

/** @type {(name: string, generatorName: string) => string } **/
export function removeGeneratorName(name, generatorName) {
export function removeGeneratorName(name: string, generatorName: string) {
// page -> Page
const pascalComponentName = pascalcase(generatorName)

Expand All @@ -41,7 +41,7 @@ export function removeGeneratorName(name, generatorName) {
return coercedName
}

export const validateName = (name) => {
export const validateName = (name: string) => {
if (name.match(/^\W/)) {
throw new Error(
'The <name> argument must start with a letter, number or underscore.',
Expand All @@ -50,7 +50,7 @@ export const validateName = (name) => {
}

// Returns all relations to other models
export const relationsForModel = (model) => {
export const relationsForModel = (model: DMMF.Model) => {
return model.fields
.filter((f) => f.relationName)
.map((field) => {
Expand All @@ -59,7 +59,7 @@ export const relationsForModel = (model) => {
}

// Returns only relations that are of datatype Int
export const intForeignKeysForModel = (model) => {
export const intForeignKeysForModel = (model: DMMF.Model) => {
return model.fields
.filter((f) => f.name.match(/Id$/) && f.type === 'Int')
.map((f) => f.name)
Expand All @@ -68,7 +68,7 @@ export const intForeignKeysForModel = (model) => {
/**
* Adds "List" to the end of words we can't pluralize
*/
export const forcePluralizeWord = (word) => {
export const forcePluralizeWord = (word: string) => {
// If word is both plural and singular (like equipment), then append "List"
if (isPlural(word) && isSingular(word)) {
return pascalcase(`${word}_list`)
Expand All @@ -77,20 +77,21 @@ export const forcePluralizeWord = (word) => {
return pluralize(word)
}

/** @type {(paramType: 'Int' | 'Float' | 'Boolean' | 'String') => string } **/
export const mapRouteParamTypeToTsType = (paramType) => {
const routeParamToTsType = {
export const mapRouteParamTypeToTsType = (
paramType: 'Int' | 'Float' | 'Boolean' | 'String',
) => {
const routeParamToTsType: Record<string, string> = {
Int: 'number',
Float: 'number',
Boolean: 'boolean',
String: 'string',
}

return routeParamToTsType[paramType] || 'unknown'
}

/** @type {(scalarType: 'String' | 'Boolean' | 'Int' | 'BigInt' | 'Float' | 'Decimal' | 'DateTime' | 'Bytes' ) => string } **/
export const mapPrismaScalarToPagePropTsType = (scalarType) => {
const prismaScalarToTsType = {
export const mapPrismaScalarToPagePropTsType = (scalarType: string) => {
const prismaScalarToTsType: Record<string, string> = {
String: 'string',
Boolean: 'boolean',
Int: 'number',
Expand All @@ -100,5 +101,6 @@ export const mapPrismaScalarToPagePropTsType = (scalarType) => {
DateTime: 'string',
Bytes: 'Uint8Array',
}

return prismaScalarToTsType[scalarType] || 'unknown'
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { recordTelemetryAttributes } from '@cedarjs/cli-helpers'
import { generate as generateTypes } from '@cedarjs/internal/dist/generate/generate'
import { getConfig } from '@cedarjs/project-config'

import { pluralize, singularize } from '../../../lib/cedarPluralize.js'
import c from '../../../lib/colors.js'
import {
generateTemplate,
Expand All @@ -29,7 +30,6 @@ import {
prepareForRollback,
addFunctionToRollback,
} from '../../../lib/rollback.js'
import { pluralize, singularize } from '../../../lib/rwPluralize.js'
import { getSchema, verifyModelName } from '../../../lib/schemaHelpers.js'
import {
relationsForModel,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/generate/sdl/sdlHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { generate as generateTypes } from '@cedarjs/internal/dist/generate/gener
import { getConfig } from '@cedarjs/project-config'
import { errorTelemetry } from '@cedarjs/telemetry'

import { pluralize } from '../../../lib/cedarPluralize.js'
import c from '../../../lib/colors.js'
import {
generateTemplate,
Expand All @@ -21,7 +22,6 @@ import {
prepareForRollback,
addFunctionToRollback,
} from '../../../lib/rollback.js'
import { pluralize } from '../../../lib/rwPluralize.js'
import {
getSchema,
getEnum,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import camelcase from 'camelcase'

import { pluralize, singularize } from '../../../lib/cedarPluralize.js'
import { transformTSToJS } from '../../../lib/index.js'
import { pluralize, singularize } from '../../../lib/rwPluralize.js'
import { getSchema, verifyModelName } from '../../../lib/schemaHelpers.js'
import { relationsForModel } from '../helpers.js'
import {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// This file is safe to statically import in the CLI
import { terminalLink } from 'termi-link'
import type { Argv, Options, PositionalOptions } from 'yargs'

// Don't import anything here that isn't already imported by the CLI
import { isTypeScriptProject } from '@cedarjs/cli-helpers'
Expand All @@ -10,9 +11,8 @@ import { isTypeScriptProject } from '@cedarjs/cli-helpers'
* The reason for this is that this in turn will call `isTypeScriptProject`,
* and that has side effects that will break `cwd` functionality if called
* before `cwd` is initialized.
* @type {() => Record<string, import('yargs').Options>}
*/
export const getYargsDefaults = () => ({
export const getYargsDefaults = (): Record<string, Options> => ({
force: {
alias: 'f',
default: false,
Expand All @@ -27,7 +27,10 @@ export const getYargsDefaults = () => ({
},
})

const appendPositionalsToCmd = (commandString, positionalsObj) => {
const appendPositionalsToCmd = (
commandString: string,
positionalsObj: Record<string, PositionalOptions>,
) => {
// Add positionals like `page <name>` + ` [path]` if specified
if (Object.keys(positionalsObj).length > 0) {
const positionalNames = Object.keys(positionalsObj)
Expand All @@ -40,16 +43,29 @@ const appendPositionalsToCmd = (commandString, positionalsObj) => {
}
}

export function createCommand(componentName, positionalsObj = {}) {
export function createCommand(
componentName: string,
positionalsObj: Record<string, PositionalOptions> = {},
) {
return appendPositionalsToCmd(`${componentName} <name>`, positionalsObj)
}

export function createDescription(componentName) {
export function createDescription(componentName: string) {
return `Generate a ${componentName} component`
}

export function createBuilder({ componentName, optionsObj, positionalsObj }) {
return (yargs) => {
interface CreateBuilderOptions {
componentName: string
optionsObj?: Record<string, Options> | (() => Record<string, Options>)
positionalsObj?: Record<string, PositionalOptions>
}

export function createBuilder({
componentName,
optionsObj,
positionalsObj,
}: CreateBuilderOptions) {
return (yargs: Argv) => {
yargs
.positional('name', {
description: `Name of the ${componentName}`,
Expand Down Expand Up @@ -99,8 +115,8 @@ export function createBuilder({ componentName, optionsObj, positionalsObj }) {
}
}

export function createHandler(componentName) {
return async function handler(argv) {
export function createHandler(componentName: string) {
return async function handler(argv: any) {
const { handler: importedHandler } = await import(
`./${componentName}/${componentName}Handler.js`
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
isPlural,
isSingular,
addSingularPlural,
} from '../rwPluralize.js'
} from '../cedarPluralize.js'

test('pluralize', () => {
expect(pluralize('books')).toEqual('books')
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/lib/__tests__/pluralHelpers.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import prompts from 'prompts'
import { test, expect } from 'vitest'

import { pluralize, singularize } from '../cedarPluralize.js'
import * as helpers from '../pluralHelpers.js'
import { pluralize, singularize } from '../rwPluralize.js'

test('validatePlural returns true if plural is single word and unique from singular', () => {
const result = helpers.validatePlural('plural', 'singular')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
import plurals from 'pluralize'

const mappings = {
const mappings: {
toSingular: Record<string, string>
toPlural: Record<string, string>
} = {
toSingular: {},
toPlural: {},
}

/**
* Find Bar in FooBazBar
*
* @type {(str: string) => string }
*/
function lastWord(str) {
function lastWord(str: string) {
const capitals = str.match(/[A-Z]/g)
const lastIndex = str.lastIndexOf(capitals?.slice(-1)[0])
const lastIndex = str.lastIndexOf(capitals?.slice(-1)[0] ?? '')

return lastIndex >= 0 ? str.slice(lastIndex) : str
Comment thread
Tobbe marked this conversation as resolved.
}

/**
* Returns the plural form of the given word
*
* @type {(word: string) => string }
*/
export function pluralize(word) {
export function pluralize(word: string) {
if (mappings.toPlural[word]) {
return mappings.toPlural[word]
}
Expand All @@ -42,10 +41,8 @@ export function pluralize(word) {

/**
* Returns the singular form of the given word
*
* @type {(word: string) => string }
*/
export function singularize(word) {
export function singularize(word: string) {
if (mappings.toSingular[word]) {
return mappings.toSingular[word]
}
Expand All @@ -60,13 +57,17 @@ export function singularize(word) {
return base + plurals.singular(plural)
}

/** @type {(word: string) => boolean } */
export function isPlural(word) {
/**
* Returns true if the given word is plural
*/
export function isPlural(word: string) {
return plurals.isPlural(lastWord(word))
}

/** @type {(word: string) => boolean } */
export function isSingular(word) {
/**
* Returns true if the given word is singular
*/
export function isSingular(word: string) {
return plurals.isSingular(lastWord(word))
}

Expand Down Expand Up @@ -95,18 +96,16 @@ export function isSingular(word) {
* Furthermore we need to handle changing the mappings (this is only done in
* tests). So if the method is called again, with input 'pokemon', 'pokemons'
* all the old mappings first have to be removed, before adding the new ones
*
* @param {string} singular
* @param {string} plural
*
* @returns {undefined}
*/
export function addSingularPlural(singular, plural) {
export function addSingularPlural(singular: string, plural: string) {
const existingPlural = Object.keys(mappings.toSingular).find(
(key) => mappings.toSingular[key] === singular,
)
delete mappings.toSingular[existingPlural]
delete mappings.toPlural[existingPlural]

if (existingPlural) {
delete mappings.toSingular[existingPlural]
delete mappings.toPlural[existingPlural]
}

mappings.toPlural[singular] = plural
mappings.toPlural[plural] = plural
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import {
findUp,
} from '@cedarjs/project-config'

import { pluralize, singularize } from './cedarPluralize.js'
import c from './colors.js'
import { addFileToRollback } from './rollback.js'
import { pluralize, singularize } from './rwPluralize.js'

export { findUp }

Expand Down
Loading