
Script Utils
import * as scriptUtils from '@green-stack/scripts/helpers/scriptUtils'
- scriptUtils.ts
A collection of utility functions for working with scripts, file paths, and workspace management in the Green Stack ecosystem.
File System Utilities
excludeDirs()
Filter function to exclude folders and directories. Returns true if the path contains a file (has an extension).
excludeDirs('path/to/file.ts') // => true
excludeDirs('path/to/folder') // => false
// Usage as a filter function:
const paths = [
'/components/Button.tsx',
'/components/Input.tsx',
'/components/',
'/schemas'
]
const filteredPaths = paths.filter(excludeDirs)
// => ['/components/Button.tsx', '/components/Input.tsx']
excludeModules()
Filter function to exclude node_modules folders. Returns true if the path does not include ‘node_modules’.
excludeModules('src/components/Button.tsx') // => true
excludeModules('node_modules/react/index.js') // => false
// Usage as a filter function:
const paths = [
'src/components/Button.tsx',
'src/components/Input.tsx',
'node_modules/react/index.js',
'node_modules/@app-core/utils.js'
]
const filteredPaths = paths.filter(excludeModules)
// => ['src/components/Button.tsx', 'src/components/Input.tsx']
globRel()
Gets the relative glob path of a glob-style selector using globSync
. The path must contain one of the workspace folder locations (‘features’, ‘packages’, or ‘apps’).
globRel('packages/**/*.ts')
// => ['packages/@green-stack-core/utils.ts', 'packages/@app-core/components.ts']
globRel('features/**/components/*.tsx')
// => ['features/@app-core/components/Button.tsx', 'features/@app-core/components/Input.tsx']
hasOptOutPatterns()
Checks if file content has opt-out patterns to determine if the file should be ignored.
const content = `
export const optOut = true
// Rest of the file...
`
hasOptOutPatterns(content) // => true
const content2 = `
// @automation optOut = true
// Rest of the file...
`
hasOptOutPatterns(content2) // => true
String Utilities
normalizeName()
Makes sure only lowercase and uppercase letters are left in a given string by removing all other characters.
normalizeName('user-profile') // => 'userprofile'
normalizeName('User_Profile_123') // => 'UserProfile'
matchMethods()
Checks that a certain method (like ‘GET’, ‘POST’, etc.) is included in a list of method names.
const methods = ['GET', 'POST', 'PUT']
matchMethods(methods, 'GET') // => true
matchMethods(methods, 'DELETE') // => false
createDivider()
Creates a code divider that’s always 100 chars wide. Can be used for documentation or code comments.
createDivider('Section Title')
// => '/* --- Section Title ----------------------------------------------------------------------------------- */'
createDivider('Section Title', true)
// => '/** --- Section Title ----------------------------------------------------------------------------------- */'
validateNonEmptyNoSpaces()
Validates that a string is not empty and does not contain spaces.
validateNonEmptyNoSpaces('validName') // => true
validateNonEmptyNoSpaces('') // => 'Please enter a non-empty value'
validateNonEmptyNoSpaces('invalid name') // => 'Please enter a value without spaces'
Handy for plop prompt input validation.
Workspace Management
parseWorkspaces()
Figure out all info about all workspaces in the monorepo and return mapped linking info for use in scripts and generators.
const workspaceInfo = parseWorkspaces(
folderLevel = '../../',
includeApps = false,
)
// => {
//
// /** -i- Map of { [path]: package.json config, ... } */
// workspaceConfigs: { ... },
//
// /** -i- Map of { [path]: pkgName, ... } */
// workspaceImports: { ... },
//
// /** -i- Map of { [pkgName]: path, ... } */
// workspacePathsMap: { ... },
//
// /** -i- Array of all workspace packages, e.g. ['features/@app-core', 'packages/@green-stack-core', ...] */
// workspacePaths: [ ... ],
//
// /** -i- Array of all workspace packages, e.g. ['@app/core', '@green-stack/core', ...] */
// workspacePackages: [ ... ]
//
// // -- Aliases and Constants --
//
// /** -i- Map of { [path]: package.json config, ... } */
// PATH_CONFIGS: { ... },
//
// /** -i- Map of { [pkgName]: package.json config, ... } */
// PKG_CONFIGS: { ... },
//
// /** -i- Map of { [path]: pkgName, ... } */
// PATH_PKGS: { ... },
//
// /** -i- Map of { [pkgName]: path, ... } */
// PKG_PATHS: { ... },
//
// }
getWorkspaceOptions()
List all the available workspaces for generators to use.
const options = getWorkspaceOptions(folderLevel = '../../', {
filter: ['@app'], // string[]
exclude = [], // string[] -i- (List of packages to exclude)
excludePackages = false, // boolean -i- (Exclude workspaces from /packages/?)
includeApps = false, // boolean -i- (Include workspaces from /apps/?)
includeGreenStack = false, // boolean -i- (Include /packages/@green-stack-core/?)
skipFormatting = false, // boolean -i- (Skip formatting the output)
prefer = [], // string[] -i- (Puts these options at the top of the list)
})
// => {
// '@app/core -- from features/@app-core': 'features/@app-core',
// '@app/ui -- from features/@app-ui': 'features/@app-ui'
// }
getAvailableSchemas()
List all the available schemas in the codebase that generators can use.
const schemas = getAvailableSchemas(folderLevel = '../../', {
schemaKey = 'schemaName', // 'schemaName' | 'schemaPath' | 'schemaOption'
includeOptOut = false, // boolean
})
// => {
// 'UserSchema': {
// schemaPath: 'features/@app-core/schemas/User.ts',
// schemaName: 'UserSchema',
// schemaFileName: 'User.ts',
// schemaOption: '@app/core - User (♻ - Schema)',
// workspacePath: 'features/@app-core',
// workspaceName: '@app/core',
// isNamedExport: true,
// isDefaultExport: false,
// schema?: ZodSchema | undefined
// },
// ... (more schemas)
// }
The default arguments for folderLevel
and schemaKey
are '../../'
and 'schemaName'
, respectively. You can adjust these based on your project structure. If you want the resulting lookup object to be keyed by either the path or option, you can pass schemaPath
or schemaOption
as the schemaKey
.
getAvailableDataBridges()
List all the available data bridges for generators to use.
const bridges = getAvailableDataBridges('../../', {
filterType?: 'query', // 'query' | 'mutation'
bridgeKey?: 'bridgeName', // 'bridgeName' | 'bridgePath' | 'bridgeOption' | 'bridgeInputOption'
allowNonGraphql?: false, // boolean
includeOptOut?: false, // boolean
})
// => {
// 'UserBridge': {
// bridgePath: 'features/@app-core/resolvers/healthCheck.bridge.ts',
// bridgeName: 'healthCheckBridge',
// bridgeOption: '@app/core >>> healthCheck() (♻ - Resolver)',
// bridgeInputOption: '@app/core >>> healthCheck() (♻ - Input)',
// workspacePath: 'features/@app-core',
// workspaceName: '@app/core',
// resolverName: 'healthCheck',
// resolverType: 'query' | 'mutation',
// operationType: 'search' | 'add' | 'update' | 'delete' | 'get' | 'list',
// fetcherName: 'healthCheckQuery',
// inputSchemaName: 'HealthCheckInput',
// outputSchemaName: 'HealthCheckOutput',
// allowedMethods: ['GET', 'POST'],
// isNamedExport: true,
// isDefaultExport: false,
// isMutation: false,
// isQuery: true,
// bridge?: DataBridgeType | undefined,
// },
// ... (more bridges)
// }
Import Management
readImportAliases()
Retrieve the import aliases from the main tsconfig.json in @app/core
.
const aliases = readImportAliases('../../')
// => {
// '@app/core/appConfig': '@app/config',
// '@app/core/schemas': '@app/schemas',
// '@app/core/utils': '@app/utils',
// '@app/core/hooks': '@app/hooks',
// '@app/core/components/styled': '@app/primitives',
// '@app/core/components': '@app/components',
// '@app/core/forms': '@app/forms',
// '@app/core/screens': '@app/screens',
// '@app/core/assets': '@app/assets',
// '@app/core/resolvers': '@app/resolvers',
// '@app/core/middleware': '@app/middleware',
// '@green-stack/core/schemas': '@green-stack/schemas',
// '@green-stack/core/navigation/index': '@green-stack/navigation',
// '@green-stack/core/navigation': '@green-stack/navigation',
// '@green-stack/core/utils': '@green-stack/utils',
// '@green-stack/core/hooks': '@green-stack/hooks',
// '@green-stack/core/components': '@green-stack/components',
// '@green-stack/core/styles/index': '@green-stack/styles',
// '@green-stack/core/styles': '@green-stack/styles',
// '@green-stack/core/forms': '@green-stack/forms',
// '@green-stack/core/context': '@green-stack/context',
// '@green-stack/core/scripts': '@green-stack/scripts',
// '@green-stack/core/svg/svg.primitives': '@green-stack/svg',
// }
swapImportAlias()
Swap an import path with an alias if a match occurs.
swapImportAlias('@app/core/appConfig')
// => '@app/config'
swapImportAlias('@app/config')
// => '@app/config'
CLI Utilities
opt()
Format a CLI option with proper styling and hierarchy.
Will grey out the anything after the --
when displayed in the terminal.
opt('Some Option')
// => 'Some Option' (nothing greyed out using ansi colors)
opt('Some Option -- This extra info is greyed out')
// => 'Some option -- This extra info is greyed out'
Helper Functions
includesOption()
Higher-order function to prefill a list of options that are checked against in the actual filter method.
const includesGetOrPost = includesOption(['GET', 'POST'])
const methods = ['GET', 'POST', 'PUT']
methods.filter(includesGetOrPost) // => ['GET', 'POST']
maybeImport()
Attempts to require()
a file, but returns an empty object if it fails or the file doesn’t exist.
// File exists
maybeImport('./config.js')
// => { port: 3000, host: 'localhost' }
// File doesn't exist
maybeImport('./nonexistent.js')
// => {}
// With error logging
maybeImport('./config.js', 'logErrors')
// => Logs error if file doesn't exist
Types
SchemaFileMeta
Metadata about a schema file:
type SchemaFileMeta = {
schema?: ZodSchema | {}
schemaPath: string
schemaName: string
schemaFileName: string
schemaOption: string
workspacePath: string
workspaceName: string
isNamedExport: boolean
isDefaultExport: boolean
}
FetcherFileMeta
Metadata about a fetcher file:
type FetcherFileMeta = {
resolverName: string
fetcherName: string
fetcherType: 'query' | 'mutation'
}
BridgeFileMeta
Metadata about a data bridge file:
type BridgeFileMeta = {
bridge?: DataBridgeType | {}
bridgePath: string
bridgeName: string
bridgeOption: string
bridgeInputOption: string
workspacePath: string
workspaceName: string
resolverName: string
resolverType: 'query' | 'mutation'
operationType: 'add' | 'update' | 'delete' | 'get' | 'list' | 'search'
fetcherName: string
inputSchemaName: string
outputSchemaName: string
allowedMethods: ALLOWED_METHODS[]
isNamedExport: boolean
isDefaultExport: boolean
isMutation: boolean
isQuery: boolean
}
Re-exports
Utils from stringUtils
Re-exports all the utility functions from @green-stack/core/utils/stringUtils
: