-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Add updated admin UI + role/password management #633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add updated admin UI + role/password management #633
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: d259c78 The changes in this PR will be included in the next version bump. This PR includes changesets to release 18 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Caution Review failedThe pull request is closed. WalkthroughAdds a pluggable Admin CRUD actions and columns system across schema, compiler, web UI, generators, and plugins; replaces legacy display-based columns with type-based columns and actions; adds built-in edit/delete and text/foreign implementations, migrations, auth admin roles, password management, and supporting UI/generator changes. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Builder as AppEntryBuilder
participant PluginStore as PluginStore
participant ActionSpec as AdminCrudActionCompilerSpec
participant ColumnSpec as AdminCrudColumnCompilerSpec
participant BuiltIns as Built-in Compilers
participant Generators as React Generators
Builder->>PluginStore: getPluginSpec(ActionSpec/ColumnSpec)
PluginStore-->>Builder: Spec instance
Builder->>ActionSpec: getCompiler(action.type, BuiltIns)
ActionSpec-->>Builder: ActionCompiler
Builder->>ColumnSpec: getCompiler(column.type, BuiltIns)
ColumnSpec-->>Builder: ColumnCompiler
Builder->>ActionCompiler: compileAction(definition, ctx)
ActionCompiler-->>Generators: adminCrud*ActionGenerator(...)
Generators-->>Builder: GeneratorBundle
Builder->>ColumnCompiler: compileColumn(definition, ctx)
ColumnCompiler-->>Generators: adminCrud*ColumnGenerator(...)
Generators-->>Builder: GeneratorBundle
sequenceDiagram
autonumber
participant UI as Admin Section UI
participant Dialog as ActionDialog
participant WebSpec as adminCrudActionWebSpec
participant BuiltIn as BUILT_IN_*_WEB_CONFIGS
participant Form as RHF + Zod
UI->>Dialog: Open (Add/Edit Action)
Dialog->>WebSpec: getActionWebConfigs(BuiltIn)
WebSpec-->>Dialog: Available configs
Dialog->>Form: build schema via createAdminCrudActionSchema
Note over Dialog,Form: Renders type-specific WebForm if present
Form-->>UI: onSave(action)
UI->>UI: add/update action in table.actions
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 28
🔭 Outside diff range comments (4)
packages/project-builder-lib/src/schema/creator/extend-parser-context-with-defaults.ts (2)
15-22: Unify ZodEffects input type: WithDefaultType should usez.input<T>(mismatch with implementation).The
WithDefaultTypetype alias still usesz.input<z.ZodOptional<T>>for the ZodEffects input type, but the implementation below usesz.input<T>. This inconsistency will leak into the public API and can cause subtle type incompatibilities.Align the alias with the implementation:
export type WithDefaultType = <T extends z.ZodTypeAny>( schema: T, defaultValue: z.input<T>, ) => z.ZodEffects< z.ZodOptional<T>, z.output<z.ZodOptional<T>>, - z.input<z.ZodOptional<T>> + z.input<T> >;
5-13: Don’t treatfalseas “empty” instripmode (data loss for boolean fields).
isEmpty(false) === truemeans valid booleanfalsevalues will be stripped toundefinedinstripmode. That’s a correctness bug for boolean fields and can corrupt user intent.Fix to only treat nullish/empty containers/empty strings as empty, not
false:function isEmpty(value: unknown): boolean { - if (Array.isArray(value)) { - return value.length === 0; - } - if (typeof value === 'object' && value !== null) { - return Object.values(value).every((val) => val === undefined); - } - return value === false || value === ''; + if (value === undefined || value === null) { + return true; + } + if (Array.isArray(value)) { + return value.length === 0; + } + if (typeof value === 'object') { + return Object.values(value).every((val) => val === undefined); + } + if (typeof value === 'string') { + return value === ''; + } + return false; }packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts (1)
86-90: Fix replaceAll usage: provide a string replacement, not a functionUsing a function as the second argument to String.prototype.replaceAll is not supported by TypeScript typings and can cause compile/runtime issues. You can precompute the replacement string since the quote is known from the pattern.
Apply this diff:
- result = result.replaceAll(pattern, (match) => { - const quote = match[0]; - return `${quote}${variable}${quote}`; - }); + const quote = pattern[0]; + const replacement = `${quote}${variable}${quote}`; + result = result.replaceAll(pattern, replacement);packages/react-generators/src/generators/admin/admin-crud-list/admin-crud-list.generator.ts (1)
170-177: Remove unused import: ErrorableLoader is not referenced in the Create button block
reactComponentsImports.ErrorableLoader.declaration()is added to the fragment imports but not used in the markup. This will likely generate an unused import in the output file.Apply this diff to remove it:
[ tsImportBuilder(['Link']).from( '@tanstack/react-router', ), tsImportBuilder(['MdAdd']).from('react-icons/md'), reactComponentsImports.Button.declaration(), - reactComponentsImports.ErrorableLoader.declaration(), ],
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts
Outdated
Show resolved
Hide resolved
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts
Show resolved
Hide resolved
| /* TPL_COMPLEX_EXPR=data?.user .email */ | ||
| function Component() {} | ||
| `; | ||
|
|
||
| expect(() => extractTsTemplateVariables(invalidContent)).toThrow( | ||
| 'Invalid replacement value "data?.user?.email"', | ||
| 'Invalid replacement value "data?.user .email"', | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
❓ Verification inconclusive
Validation case update looks correct; please ensure we also cover the now-valid optional chaining case
Switching the invalid value to include a space aligns with the relaxed rules (optional chaining should be valid). Please verify we have a positive test asserting that data?.user?.email is accepted somewhere in the suite (e.g., parse-simple-replacements.unit.test.ts). If missing, I can provide a patch.
Run this to confirm a positive test exists:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Look for a test that includes the now-valid optional chaining replacement value
rg -nP -C2 'data\?\.user\?\.email' --type=ts --glob '**/*.unit.test.ts'Length of output: 93
Add a positive test for the valid optional‐chaining case
I ran a search across all *.unit.test.ts files and didn’t find any existing test that asserts data?.user?.email is accepted. Please add a test case—e.g. in parse-simple-replacements.unit.test.ts (or alongside the other “simple” template‐variable tests)—to verify that data?.user?.email now passes validation.
-
No matches for
data?.user?.emailin the current test suite -
Add something like:
const validContent = ` /* TPL_SIMPLE_EXPR=data?.user?.email */ function Component() {} `; expect(extractTsTemplateVariables(validContent)).toEqual([ 'data?.user?.email', ]);
🤖 Prompt for AI Agents
In
packages/core-generators/src/renderers/typescript/extractor/extract-ts-template-variables-simple.unit.test.ts
around lines 185 to 191, add a positive unit test that asserts the extractor
accepts optional-chaining with multiple safe-navigation operators (e.g.
"data?.user?.email"); create a test block with content containing the comment /*
TPL_SIMPLE_EXPR=data?.user?.email */ and call
expect(extractTsTemplateVariables(validContent)).toEqual(['data?.user?.email'])
to ensure the value passes validation.
| // Check if the value already exists in the template (would prevent extraction) | ||
| // We check the original template, not the processed one | ||
| const valuePattern = new RegExp( | ||
| `\\b${contents.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)}\\b`, | ||
| ); | ||
| if (valuePattern.test(template)) { | ||
| throw new Error( | ||
| `The template contents contain the value "${contents}" which would prevent ` + | ||
| 'template extraction from working correctly. Please ensure that replacement variable values ' + | ||
| 'are not present in the original template file.', | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boundary check can miss values starting/ending with non-word chars; avoid dynamic regex entirely
Using word boundaries (\b) only guards transitions between [A-Za-z0-9_] and non-word chars. Since allowed values include non-word characters like $, /, ., and -, \b will not form a boundary at the start/end for such characters. Example: contents="$FOO" present in the template will not be detected because there’s no word boundary at the start of "$FOO". This can silently allow values that already exist in the template and break extraction later.
Additionally, static analysis flagged dynamic regex construction. While you escape special chars and restrict allowed sets, we can remove the dynamic regex altogether and precisely model “standalone occurrence” using simple indexOf + neighbor checks against the same allowed char class used by the validator.
Apply this diff to replace the dynamic regex check:
- // Check if the value already exists in the template (would prevent extraction)
- // We check the original template, not the processed one
- const valuePattern = new RegExp(
- `\\b${contents.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)}\\b`,
- );
- if (valuePattern.test(template)) {
+ // Check if the value already exists in the template (would prevent extraction)
+ // We check the original template, not the processed one
+ if (containsStandaloneValue(template, contents)) {
throw new Error(
`The template contents contain the value "${contents}" which would prevent ` +
'template extraction from working correctly. Please ensure that replacement variable values ' +
'are not present in the original template file.',
);
}And add this helper (place it near escapeReplacement):
// Determines if `needle` occurs in `haystack` as a standalone token with respect to
// the allowed character class used for simple replacements: [A-Za-z0-9_$/.-]
function containsStandaloneValue(haystack: string, needle: string): boolean {
if (needle.length === 0) return false;
const isAllowed = (ch: string | undefined) =>
!!ch && /[A-Za-z0-9_$/.-]/.test(ch);
let idx = haystack.indexOf(needle);
while (idx !== -1) {
const prev = idx > 0 ? haystack[idx - 1] : undefined;
const next =
idx + needle.length < haystack.length
? haystack[idx + needle.length]
: undefined;
// Consider it “standalone” if both neighbors are either absent or not allowed
if (!isAllowed(prev) && !isAllowed(next)) {
return true;
}
idx = haystack.indexOf(needle, idx + 1);
}
return false;
}This:
- Correctly detects values starting/ending with non-word chars.
- Eliminates dynamic regex construction (addressing the static analysis warning).
- Aligns the boundary definition with the validator’s allowed character set.
🧰 Tools
🪛 ast-grep (0.38.6)
[warning] 89-91: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(
\\b${contents.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw$&)}\\b,
)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
...tors/pothos/pothos/templates/src/plugins/graphql/FieldWithInputPayloadPlugin/global-types.ts
Show resolved
Hide resolved
...tors/admin-crud-reset-password-action/templates/routes/-components/password-reset-dialog.tsx
Show resolved
Hide resolved
...tors/admin-crud-reset-password-action/templates/routes/-components/password-reset-dialog.tsx
Show resolved
Hide resolved
plugins/plugin-auth/src/local-auth/admin/schema/roles-column.ts
Outdated
Show resolved
Hide resolved
plugins/plugin-auth/src/local-auth/admin/schema/roles-column.ts
Outdated
Show resolved
Hide resolved
| await prisma.$transaction([ | ||
| prisma.userRole.deleteMany({ | ||
| where: { userId, role: { notIn: validRoles } }, | ||
| }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid deleting built-in roles from the DB.
You filter built-ins out of validRoles, but deleteMany removes any role not in validRoles, which may unintentionally delete built-in roles if they are persisted. Limit deletions to assignable (non-built-in) roles only.
Apply this diff to restrict the deletion set:
await prisma.$transaction([
prisma.userRole.deleteMany({
- where: { userId, role: { notIn: validRoles } },
+ where: {
+ userId,
+ role: { in: assignableRoles, notIn: validRoles },
+ },
}),Add the assignableRoles helper near the validRoles computation:
// Place below the validRoles computation (after Line 33)
const assignableRoles = Object.entries(AUTH_ROLE_CONFIG)
.filter(([, cfg]) => !cfg.builtIn)
.map(([name]) => name);🤖 Prompt for AI Agents
In
plugins/plugin-auth/src/local-auth/core/generators/auth-module/templates/module/services/user-roles.service.ts
around lines 34 to 37, the prisma.deleteMany currently removes any role not in
validRoles which can accidentally delete built-in roles; define an
assignableRoles helper immediately below the validRoles computation that
collects role names from AUTH_ROLE_CONFIG where cfg.builtIn is false, then
restrict the deleteMany where clause so it only deletes roles that are
assignable and not in validRoles (i.e., require role ∈ assignableRoles AND role
∉ validRoles) to ensure built-in roles are never removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
packages/project-builder-lib/src/schema/creator/extend-parser-context-with-defaults.ts (1)
21-28: Fix ZodEffects input generic mismatch between type alias and implementation.WithDefaultType returns ZodEffects whose Input is z.input<z.ZodOptional>, but the implementation annotates the return as z.input. All branches return effects built on optionalSchema, so their Input is actually z.input<z.ZodOptional>. This mismatch will fail type-checking.
Apply this diff to align the implementation with the alias and with the actual return type of all branches:
- ): z.ZodEffects<z.ZodOptional<T>, z.output<z.ZodOptional<T>>, z.input<T>> { + ): z.ZodEffects<z.ZodOptional<T>, z.output<z.ZodOptional<T>>, z.input<z.ZodOptional<T>>> {If the intended new API is to expose ZodEffects with Input = z.input, we’ll need a different construction pattern (and likely a cast) to avoid widening the accepted input to include undefined; happy to draft that if that’s the goal.
Also applies to: 44-48
♻️ Duplicate comments (3)
packages/react-generators/src/generators/core/react-components/templates/components/ui/sidebar.tsx (1)
563-569: Same spread-order bug: generated code will drop the mobile-dismiss logic if consumers passonClick.
{...props}after your inlineonClickoverrides it. Fix the order (or destructureonClickand spread the rest) to ensure dismissal runs.Apply this diff:
className={cn(sidebarMenuButtonVariants({ variant, size }), className)} - onClick={(event) => { - onClick?.(event); - if (isMobile && !event.defaultPrevented) { - toggleSidebar(); - } - }} - {...props} + {...props} + onClick={(event) => { + onClick?.(event); + if (isMobile && !event.defaultPrevented) { + toggleSidebar(); + } + }}Alternative (template-friendly): destructure
onClickasuserOnClickand spread the rest last, mirroring the suggestion in ui-components.packages/core-generators/src/renderers/typescript/renderers/template.ts (1)
90-99: Template boundary check uses safe regex construction but still creates dynamic regex.The use of
escapeRegExp(contents)provides safe regex construction, but this still creates a dynamic regex from user input, which static analysis flagged as a potential ReDoS risk.The boundary check can miss values starting/ending with non-word chars and uses dynamic regex construction. Apply the solution from the previous review to use
containsStandaloneValuehelper instead.packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts (1)
47-47: Import declarations skipped intentionally.Based on previous clarification, skipping import declarations allows unused imports to be removed properly after template variable replacements are applied.
🧹 Nitpick comments (1)
packages/project-builder-lib/src/schema/creator/extend-parser-context-with-defaults.ts (1)
62-70: Clarify “strip” semantics or compare against defaultValue.The comment says “remove values matching defaults,” but the code strips only “empty” values and does not use defaultValue. Either update the comment to reflect the behavior, or implement comparison to defaultValue (deep-equal for objects).
Minimal doc fix:
- // Use transform to remove values matching defaults after validation + // Use transform to strip empty values after validationIf you do want to strip values equal to defaultValue, we can add a deep-equality check (without adding deps) — say a small utility for primitives + shallow objects, or a guarded deep-equal where T is known to be JSON-like. Want me to draft that?
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (9)
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts(3 hunks)packages/core-generators/src/renderers/typescript/renderers/template.ts(2 hunks)packages/project-builder-lib/src/schema/creator/extend-parser-context-with-defaults.ts(2 hunks)packages/react-generators/src/generators/admin/admin-crud-delete-action/admin-crud-delete-action.generator.ts(1 hunks)packages/react-generators/src/generators/admin/admin-crud-edit-action/admin-crud-edit-action.generator.ts(1 hunks)packages/react-generators/src/generators/admin/admin-crud-list/admin-crud-list.generator.ts(7 hunks)packages/react-generators/src/generators/core/react-components/templates/components/ui/sidebar.tsx(3 hunks)packages/ui-components/src/components/ui/sidebar/sidebar.tsx(3 hunks)plugins/plugin-auth/src/local-auth/admin/schema/roles-column.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- plugins/plugin-auth/src/local-auth/admin/schema/roles-column.ts
- packages/react-generators/src/generators/admin/admin-crud-edit-action/admin-crud-edit-action.generator.ts
- packages/ui-components/src/components/ui/sidebar/sidebar.tsx
- packages/react-generators/src/generators/admin/admin-crud-delete-action/admin-crud-delete-action.generator.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.{ts,tsx}: Import UI components from the@baseplate-dev/ui-componentspackage as shown in the provided examples.
Use both standalone and React Hook Form controller variants for form components from@baseplate-dev/ui-componentsas appropriate.
If a particular interface or type is not exported, change the file so it is exported.
**/*.{ts,tsx}: TypeScript with strict type checking
Always include return types on top-level functions including React components (React.ReactElement)
Include absolute paths in import statements via tsconfig paths (@src/is the alias forsrc/)
If a particular interface or type is not exported, change the file so it is exported
Files:
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.tspackages/project-builder-lib/src/schema/creator/extend-parser-context-with-defaults.tspackages/react-generators/src/generators/core/react-components/templates/components/ui/sidebar.tsxpackages/react-generators/src/generators/admin/admin-crud-list/admin-crud-list.generator.tspackages/core-generators/src/renderers/typescript/renderers/template.ts
**/*.{js,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)
Node 16 module resolution - include file extensions in imports (
.js)
Files:
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.tspackages/project-builder-lib/src/schema/creator/extend-parser-context-with-defaults.tspackages/react-generators/src/generators/core/react-components/templates/components/ui/sidebar.tsxpackages/react-generators/src/generators/admin/admin-crud-list/admin-crud-list.generator.tspackages/core-generators/src/renderers/typescript/renderers/template.ts
**/*.{ts,tsx,js}
📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)
**/*.{ts,tsx,js}: Sort imports by group: external libs first, then local imports
Use camelCase for variables/functions, PascalCase for types/classes
Order functions such that functions are placed below the variables/functions they use
We use the prefer using nullish coalescing operator (??) ESLint rule instead of a logical or (||), as it is a safer operator
Use console.info/warn/error instead of console.log
Files:
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.tspackages/project-builder-lib/src/schema/creator/extend-parser-context-with-defaults.tspackages/react-generators/src/generators/core/react-components/templates/components/ui/sidebar.tsxpackages/react-generators/src/generators/admin/admin-crud-list/admin-crud-list.generator.tspackages/core-generators/src/renderers/typescript/renderers/template.ts
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/code-style.mdc)
Use kebab-case for file names
Files:
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.tspackages/project-builder-lib/src/schema/creator/extend-parser-context-with-defaults.tspackages/react-generators/src/generators/core/react-components/templates/components/ui/sidebar.tsxpackages/react-generators/src/generators/admin/admin-crud-list/admin-crud-list.generator.tspackages/core-generators/src/renderers/typescript/renderers/template.ts
**/*.tsx
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.tsx: When using form components, integrate them with React Hook Form by passing thecontrolprop fromuseForm().
Use layout components such asSidebarLayout,Card, andBreadcrumbfrom@baseplate-dev/ui-componentsto structure pages as shown in the example.
Use interactive dialog components likeDialog,ConfirmDialog, anduseConfirmDialogfrom@baseplate-dev/ui-componentsfor modal interactions.
Files:
packages/react-generators/src/generators/core/react-components/templates/components/ui/sidebar.tsx
🧠 Learnings (6)
📚 Learning: 2025-08-17T01:30:00.333Z
Learnt from: kingston
PR: halfdomelabs/baseplate#633
File: packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts:47-48
Timestamp: 2025-08-17T01:30:00.333Z
Learning: In template extraction systems like apply-simple-replacements.ts, it's intentional to skip processing import declarations to allow unused imports to be removed properly after template variable replacements are applied.
Applied to files:
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.tspackages/core-generators/src/renderers/typescript/renderers/template.ts
📚 Learning: 2025-07-22T09:10:31.413Z
Learnt from: CR
PR: halfdomelabs/baseplate#0
File: .cursor/rules/code-style.mdc:0-0
Timestamp: 2025-07-22T09:10:31.413Z
Learning: Applies to **/*.{ts,tsx} : Include absolute paths in import statements via tsconfig paths (`src/` is the alias for `src/`)
Applied to files:
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts
📚 Learning: 2025-07-22T09:09:23.016Z
Learnt from: CR
PR: halfdomelabs/baseplate#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-22T09:09:23.016Z
Learning: Applies to **/*.{ts,tsx} : If a particular interface or type is not exported, change the file so it is exported.
Applied to files:
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts
📚 Learning: 2025-07-22T09:10:31.413Z
Learnt from: CR
PR: halfdomelabs/baseplate#0
File: .cursor/rules/code-style.mdc:0-0
Timestamp: 2025-07-22T09:10:31.413Z
Learning: Applies to **/*.{ts,tsx} : TypeScript with strict type checking
Applied to files:
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts
📚 Learning: 2025-07-22T09:10:31.413Z
Learnt from: CR
PR: halfdomelabs/baseplate#0
File: .cursor/rules/code-style.mdc:0-0
Timestamp: 2025-07-22T09:10:31.413Z
Learning: Applies to **/*.{ts,tsx} : If a particular interface or type is not exported, change the file so it is exported
Applied to files:
packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts
📚 Learning: 2025-05-05T06:35:57.528Z
Learnt from: kingston
PR: halfdomelabs/baseplate#521
File: packages/sync/src/templates/text-template/render-text-template-file-action.ts:97-106
Timestamp: 2025-05-05T06:35:57.528Z
Learning: In the text template renderer, validation of template variable values against template content is only necessary when preparing for future template extraction (when shouldWriteMetadata is true). This validation prevents extraction errors by ensuring variable values don't already exist in the template content.
Applied to files:
packages/core-generators/src/renderers/typescript/renderers/template.ts
🧬 Code Graph Analysis (3)
packages/react-generators/src/generators/core/react-components/templates/components/ui/sidebar.tsx (2)
packages/react-generators/src/generators/core/react-components/templates/components/ui/tooltip.tsx (1)
TooltipContent(63-63)packages/ui-components/src/components/ui/sidebar/sidebar.tsx (1)
useSidebar(776-776)
packages/react-generators/src/generators/admin/admin-crud-list/admin-crud-list.generator.ts (6)
packages/react-generators/src/providers/routes.ts (1)
reactRoutesProvider(37-38)packages/react-generators/src/generators/admin/admin-crud-queries/admin-crud-queries.generator.ts (1)
adminCrudQueriesProvider(64-65)packages/react-generators/src/generators/admin/_providers/admin-crud-action-container.ts (2)
adminCrudActionContainerProvider(23-24)AdminCrudAction(7-16)packages/react-generators/src/generators/admin/_providers/admin-crud-column-container.ts (2)
adminCrudColumnContainerProvider(16-17)AdminCrudColumn(5-9)packages/core-generators/src/renderers/typescript/utils/ts-code-utils.ts (1)
TsCodeUtils(85-582)packages/core-generators/src/renderers/typescript/imports/builder.ts (1)
tsImportBuilder(74-82)
packages/core-generators/src/renderers/typescript/renderers/template.ts (2)
packages/core-generators/src/renderers/typescript/extractor/parse-simple-replacements.ts (1)
isValidSimpleReplacementValue(102-104)packages/core-generators/src/renderers/typescript/utils/ts-code-utils.ts (1)
template(446-467)
🪛 ast-grep (0.38.6)
packages/core-generators/src/renderers/typescript/renderers/template.ts
[warning] 91-91: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(\\b${escapeRegExp(contents)}\\b)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Lint
- GitHub Check: test
- GitHub Check: Test E2E
🔇 Additional comments (39)
packages/project-builder-lib/src/schema/creator/extend-parser-context-with-defaults.ts (1)
23-23: Good change: defaultValue as z.input.This aligns default inputs with Zod’s input typing and avoids unnecessary conversions at the API boundary.
packages/react-generators/src/generators/core/react-components/templates/components/ui/sidebar.tsx (6)
31-37: LGTM! Good documentation addition.The documentation block clearly describes the component source and the new dismiss functionality, with a helpful reference to the GitHub issue.
46-54: LGTM! Context interface correctly updated.The
SidebarContextPropsinterface has been properly updated to include thetoggleSidebarfunction, maintaining type safety for the new functionality.
102-109: LGTM! Toggle function implementation is correct.The
toggleSidebarfunction correctly handles both mobile and desktop states, using appropriate setters for each mode.
133-144: LGTM! Context value properly includes new function.The
toggleSidebarfunction is correctly included in both the context value object and the dependency array for theuseMemohook.
546-546: LGTM! Props interface correctly updated.The
onClickprop has been properly added to the component's props interface.
554-554: LGTM! Hook usage updated correctly.The
useSidebarhook call has been updated to destructure the newtoggleSidebarfunction along with the existing values.packages/core-generators/src/renderers/typescript/renderers/template.ts (7)
1-1: Import added for regex escaping.The addition of
escapeRegExpfromes-toolkitprovides safe regex construction for template validation.
9-12: Import structure updated for enhanced validation.The import now includes
isValidSimpleReplacementValuefunction which aligns with the broader validation improvements across the typescript renderers.
67-69: Simplified metadata check avoids optional chaining.The direct property check
!(key in variableMetadata)is more efficient than optional chaining for this validation path.
71-71: Direct property access after validation.Since Line 67-69 already ensures the key exists in
variableMetadata, this direct access is safe and consistent.
74-81: Enhanced validation with better error messaging.The replacement of regex-based validation with
isValidSimpleReplacementValueprovides consistent validation logic. The error message clearly specifies allowed characters and suggests alternatives for complex values.
82-88: Duplicate value detection moved after validation.The logical flow now validates the value format first, then checks for duplicates. This ordering provides better error messaging to users.
101-101: Consistent variable assignment after all validations.The assignment to
replacementVariablesoccurs after all validation checks pass, ensuring data integrity.packages/core-generators/src/renderers/typescript/extractor/apply-simple-replacements.ts (7)
2-2: Import statement includes ts for JSX configuration.The addition of
tsimport enables proper JSX configuration in the compiler options.
36-36: JSX configuration uses proper enum value.The change from
jsx: 1tojsx: ts.JsxEmit.ReactJSXuses the proper TypeScript enum value, making the code more maintainable and explicit.
41-41: File extension changed to .tsx for JSX support.The change from 'temp.ts' to 'temp.tsx' ensures TypeScript properly parses JSX content, which is necessary given the ReactJSX configuration.
44-44: Statement collection includes comments.Using
getStatementsWithComments()instead ofgetStatements()ensures comment preservation during AST processing.
49-64: In-place AST modification approach.The new approach processes each statement individually, applying replacements to the statement text and updating the AST in-place. This is more efficient than the previous collection-and-reassembly approach.
66-66: Full text emission after AST transformations.Using
sourceFile.getFullText()leverages ts-morph's built-in text generation rather than manual assembly, which is more reliable for preserving formatting and trivia.
82-89: String literal replacement simplified.The new approach generates literal pattern strings for different quote types and uses
replaceAllinstead of regex construction. This eliminates dynamic regex creation and improves performance.packages/react-generators/src/generators/admin/admin-crud-list/admin-crud-list.generator.ts (18)
22-22: Type import added for action system.The import of
AdminCrudActiontype supports the new dynamic action system being introduced.
26-26: Provider import for action container.Adding
adminCrudActionContainerProviderenables the runtime action registration system.
45-45: Renderers integrated into task dependencies.The addition of
renderers: ADMIN_ADMIN_CRUD_LIST_GENERATED.renderers.taskenables the new renderer-based approach for generating templates.
53-53: Renderer provider wired into dependencies.The renderer provider dependency enables access to the table renderer used in the build process.
56-56: Action container exported.The export of
adminCrudActionContainermakes it available for other generators to register actions dynamically.
64-64: Renderer dependency added to run function.The
renderersdependency provides access to the table renderer used later in the build process.
68-68: Action array initialized.The initialization of an empty
actionsarray prepares for dynamic action registration.
78-81: Action container provider implementation.The provider implementation provides
addActionfor registering actions andgetModelNamefor context. The interface is clean and focused.
88-88: Actions sorted by order.Sorting actions by their
orderproperty ensures consistent action positioning in the UI.
129-129: Action GraphQL fields merged.The inclusion of action GraphQL fields in the row query ensures all necessary data is available for action execution.
152-152: Table component props include loader data.The table component receives both the data items and extra props from data loaders, maintaining the existing loader integration pattern.
187-201: Dynamic header generation with actions column.The header generation now includes an "Actions" column when actions exist, with proper styling (
w-12class for width). The conditional rendering ensures the column only appears when needed.
208-213: Actions filtered by position.The separation of inline and dropdown actions based on their
positionproperty enables different rendering strategies for each action type.
215-242: Action fragments properly constructed.The inline actions are merged directly, while dropdown actions are wrapped in a proper dropdown menu structure with appropriate UI components. The use of
MdMoreVerticon and accessibility considerations (sr-onlyspan) show attention to UX details.
244-254: Action cell fragment with proper layout.The action cell uses flexbox layout (
flex items-center gap-2) to properly align inline and dropdown actions. The conditional rendering ensures the cell is only added when actions exist.
257-257: Table rendering uses new renderer system.The switch from direct template rendering to
renderers.table.renderenables the extensible renderer-based approach introduced in this PR.
267-270: Cells include action cell conditionally.The spread of
cellsfollowed by the conditionalactionCellFragmentensures the actions column is positioned correctly at the end of the table.
284-290: Action-related template variables.The new template variables
TPL_ACTION_HOOKSandTPL_ACTION_SIBLING_COMPONENTSenable per-action hooks and components to be injected into the generated table template.
Summary by CodeRabbit
New Features
Improvements
Migration
Chores