Skip to content
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: allow users to import from node_modules #1021

Conversation

TGTGamer
Copy link
Contributor

@TGTGamer TGTGamer commented Feb 20, 2024

Goal: Closes #1008

Caution

Test for IDE's not completed due to errors running on Windows & Codespace Development Environments.
 ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL  [email protected] build: "./gradlew buildPlugin"

Summary

This code defines a function named resolveImportUri that takes a ModelImport object as input and returns a URI object or undefined. The function is responsible for resolving the import path of the ModelImport object.

Example Usage

const imp: ModelImport = {
  ...
  path: '@eventiva/myModel'
};

const result = resolveImportUri(imp);
console.log(result); // Output: undefined or URI object for "node_modules/@eventiva/myModel.zmodel"

Code Analysis

Inputs

  • imp (type: ModelImport): The ModelImport object that contains the import path to be resolved.

Flow

  1. Check if the path property of the imp object is undefined, null, or an empty string. If true, return undefined.
  2. If the path does not end with '.zmodel', append '.zmodel' to the path.
  3. Check if the path is a relative path, an absolute path (Unix), or an absolute path (Windows). If true, skip to step 6.
  4. Call the findNodeModulesFile function with the path as an argument to find the file location in the node_modules directory.
  5. If the file location is empty, return undefined.
  6. Get the directory URI of the imp object using the getDocument and Utils.dirname functions.
  7. Resolve the path using the Utils.resolvePath function with the directory URI and the modified path.
  8. Return the resolved URI.

Outputs

  • URI object: The resolved URI of the import path.
  • undefined: If the import path cannot be resolved.

Tests

packages/schema test$ ZENSTACK_TEST=1 jest "--silent" "--forceExit"
[76 lines collapsed]
│   machine-id-utils.ts                  |   71.62 |    33.33 |     100 |   71.62 | 25-26,37-41,43-47,54-57,59,65-66,72-73                                                                                          …
│   pkg-utils.ts                         |   45.12 |       50 |   28.57 |   45.12 | 64,68-118,120-134,141-155,157-164                                                                                               …
│   typescript-expression-transformer.ts |   74.12 |    74.54 |      70 |   74.12 | 26-27,80,92,98,103-105,109-110,113,115-118,131-132,138-139,143-144,166-178,209-212,216-218,222-224,228-230,268-269,274-284,304-3…
│   version-utils.ts                     |   84.61 |       50 |     100 |   84.61 | 10-11                                                                                                                           …
│ ---------------------------------------|---------|----------|---------|---------|---------------------------------------------------------------------------------------------------------------------------------…
│ Test Suites: 17 passed, 17 total
│ Tests:       124 passed, 124 total
│ Snapshots:   0 total
│ Time:        534.871 s
└─ Done in 8m 57.3s

Summary by CodeRabbit

Summary by CodeRabbit

  • Refactor
    • Updated the logic for locating package.json files across various modules for improved path resolution.
  • New Features
    • Enhanced the schema generation process by refining the path resolution logic.
    • Introduced a new method for handling module file searches within node_modules directories.
  • Chores
    • Added a deprecation notice for the findPackageJson function, encouraging the use of the new path searching methods.

Copy link
Contributor

coderabbitai bot commented Feb 20, 2024

Walkthrough

Walkthrough

The updates across various files in the schema package primarily involve enhancing the path resolution and import capabilities, focusing on better integration with node_modules for external package support. This is achieved by replacing the findPackageJson function with findUp for more versatile path searching and introducing findNodeModulesFile for direct node_modules access. These changes collectively aim to streamline extending schemas from external packages, addressing the need for easier importation and ensuring a single source of truth for schemas across projects.

Changes

File(s) Summary
.../cli/cli-util.ts
.../plugins/prisma/schema-generator.ts
Replaced findPackageJson with findUp from pkg-utils, altering path resolution for package.json.
.../utils/ast-utils.ts Added findNodeModulesFile import; modified resolveImportUri for enhanced path handling including .zmodel extensions and node_modules support.
.../utils/pkg-utils.ts Updated findUp function for multiple paths and clarity; added findNodeModulesFile and deprecated findPackageJson.

Assessment against linked issues

Objective Addressed Explanation
Extended import for package manager exportability (#1008) The changes directly support the objective by improving the mechanism for importing from node_modules, thus facilitating extension from external packages. No further explanation is required as the modifications to ast-utils.ts and pkg-utils.ts align with the requested feature enhancement.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

Note: Auto-reply has been disabled for this repository by the repository owner. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 4398231 and 663e247.
Files selected for processing (4)
  • packages/schema/src/cli/cli-util.ts (2 hunks)
  • packages/schema/src/plugins/prisma/schema-generator.ts (2 hunks)
  • packages/schema/src/utils/ast-utils.ts (2 hunks)
  • packages/schema/src/utils/pkg-utils.ts (3 hunks)
Additional comments: 8
packages/schema/src/utils/ast-utils.ts (2)
  • 21-21: The addition of the findNodeModulesFile import from pkg-utils is necessary for the new functionality introduced in the resolveImportUri function. This change aligns with the PR's objective to enhance import capabilities, specifically for handling imports from node_modules.
  • 98-114: The modifications to the resolveImportUri function introduce several key enhancements:
  • Adding a .zmodel extension to paths that don't already end with it.
  • Handling different path formats (relative, absolute Unix, absolute Windows).
  • Utilizing findNodeModulesFile for resolving paths within node_modules.

These changes are crucial for supporting the feature of importing models from node_modules. However, there are a few considerations:

  • The check for absolute Windows paths uses a regex that specifically looks for paths starting with a drive letter followed by :\\. Ensure this regex accurately captures all valid Windows absolute paths.
  • The use of findNodeModulesFile assumes that if a path does not start with ., /, or match the Windows absolute path regex, it must be a module within node_modules. This logic seems sound, but it's important to verify that this assumption holds in all intended use cases.
  • The function now mutates imp.path directly by appending .zmodel if necessary. While this should work as intended, consider the implications of mutating function arguments and whether this could have unintended side effects elsewhere.

Overall, these changes significantly improve the flexibility and capability of the resolveImportUri function, aligning with the PR's goals.

packages/schema/src/utils/pkg-utils.ts (3)
  • 32-40: The refactoring of the findUp function introduces support for searching multiple paths and improves clarity and extensibility. This change is significant for the PR's objective to enhance path resolution capabilities. The function now supports returning either a single path or an array of paths, depending on the multiple flag. This flexibility is crucial for locating files within nested directories, such as node_modules. The implementation appears to be correct and efficiently uses recursion to traverse up the directory tree. However, ensure thorough testing, especially for edge cases like symbolic links or permission issues in certain directories.
  • 56-65: The addition of the findNodeModulesFile function is a key part of the PR's objective to enable importing from node_modules. This function uses the enhanced findUp to locate the node_modules directory and then attempts to find the specified file within it. The logic for splitting the provided name into folder and file parts and constructing the file location is sound. However, consider adding more detailed error handling or logging to help diagnose issues when files cannot be found. Additionally, ensure that this function is thoroughly tested with various directory structures and naming conventions within node_modules.
  • 136-140: The deprecation notice for findPackageJson in favor of using findUp is a good practice, as it encourages the use of the more flexible and generalized findUp function. This change aligns with the PR's goal of improving path resolution logic. Ensure that all references to findPackageJson within the project have been updated to use findUp, and consider adding a warning log or console output when findPackageJson is used, to alert developers of the deprecation.
packages/schema/src/cli/cli-util.ts (1)
  • 283-283: The replacement of findPackageJson with findUp in the getDefaultSchemaLocation function is a direct application of the changes made in pkg-utils.ts. This update leverages the enhanced capabilities of findUp to locate the package.json file, which is a more flexible and robust approach than the previous findPackageJson function. This change is consistent with the PR's objectives and improves the logic for schema location retrieval. Ensure that the rest of the codebase has been updated accordingly to use findUp where findPackageJson was previously used.
packages/schema/src/plugins/prisma/schema-generator.ts (2)
  • 51-51: The import statement for findUp from ../../utils/pkg-utils replaces the previous findPackageJson. This change aligns with the PR's objective to enhance path resolution logic, particularly for locating package.json files. Ensure that all instances where findPackageJson was used are now correctly utilizing findUp with the appropriate arguments and handling its return values correctly.
  • 453-453: The usage of findUp to locate package.json in the function getDefaultPrismaOutputFile is a direct application of the newly imported utility. This change is crucial for the feature allowing users to import models from node_modules by improving the path resolution logic. It's important to verify that the findUp function is correctly implemented to handle both the search for package.json and the resolution of the Prisma schema output file path based on the zenstack.prisma configuration within package.json. Additionally, ensure that error handling and edge cases, such as the absence of package.json or invalid configurations, are adequately addressed.

@TGTGamer TGTGamer mentioned this pull request Feb 22, 2024
@TGTGamer
Copy link
Contributor Author

@ymc9 could you advise where you would like me to write tests in for this, and what specific tests you'd like me to run? Is there a node_module which has a zmodel which we can import as part of the development dependancies or would you like me to initialise a very basic package just to host as that dependancy?

@ymc9
Copy link
Member

ymc9 commented Feb 22, 2024

@ymc9 could you advise where you would like me to write tests in for this, and what specific tests you'd like me to run? Is there a node_module which has a zmodel which we can import as part of the development dependancies or would you like me to initialise a very basic package just to host as that dependancy?

Currently, the only zmodel that resides in node_modules is "@zenstackhq/openapi/plugin.zmodel". The "plugin.zmodel" will be automatically loaded when a plugin is enabled. I believe you can also use it to test the import mechanism without using the plugin. A bit hacky though. Alternatively, you can also just scaffold an npm project in the test case, contrive a dependency, and smuggle a zmodel inside of it.

I think the test cases can belong to "packages/schema/tests/schema/...". What you think?

@TGTGamer TGTGamer force-pushed the 1008-extended-import-utilising-package-manager-to-provide-exportability branch from 1f8bc15 to 83b6f37 Compare March 2, 2024 21:24
multiple paths and add detailed JSDoc comments for better understanding and
documentation
…s conditions to handle different scenarios and improve flexibility in importing modules
@TGTGamer TGTGamer force-pushed the 1008-extended-import-utilising-package-manager-to-provide-exportability branch from 83b6f37 to 5a5dcd4 Compare March 2, 2024 21:40
@TGTGamer TGTGamer marked this pull request as ready for review March 2, 2024 21:43
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 0f9f025 and 5a5dcd4.
Files selected for processing (2)
  • packages/schema/src/utils/ast-utils.ts (2 hunks)
  • packages/schema/src/utils/pkg-utils.ts (3 hunks)
Additional comments: 2
packages/schema/src/utils/ast-utils.ts (1)
  • 21-21: The addition of findNodeModulesFile from pkg-utils is appropriate for the new functionality introduced in resolveImportUri. This change aligns with the PR's objective to enhance import capabilities from node_modules.
packages/schema/src/utils/pkg-utils.ts (1)
  • 135-135: The deprecation of findPackageJson in favor of findUp is noted. This change aligns with the PR's objective to refine type definitions and improve functionality. Ensure that all references to findPackageJson are updated to use findUp where applicable.
Verification successful

Given the findings, it's necessary to further investigate whether the remaining reference to findPackageJson is actively used in the codebase or if it's simply its definition. To clarify this, I will search for calls to findPackageJson excluding its definition.


The verification process reveals that while findPackageJson is still defined in the codebase, there are no active calls to this function outside of its definition. This supports the review comment's implication that findPackageJson has been deprecated in favor of findUp, aligning with the PR's objective to refine type definitions and improve functionality. Therefore, the review comment is consistent with the findings in the codebase.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for any remaining references to findPackageJson in the codebase.
rg --type ts 'findPackageJson'

Length of output: 124



Script:

#!/bin/bash
# Search for calls to findPackageJson excluding its definition
rg --type ts 'findPackageJson' | grep -v 'export function findPackageJson'

Length of output: 74

packages/schema/src/utils/ast-utils.ts Outdated Show resolved Hide resolved
packages/schema/src/utils/pkg-utils.ts Outdated Show resolved Hide resolved
packages/schema/src/utils/ast-utils.ts Show resolved Hide resolved
packages/schema/src/utils/pkg-utils.ts Outdated Show resolved Hide resolved
packages/schema/src/utils/pkg-utils.ts Show resolved Hide resolved
@ymc9
Copy link
Member

ymc9 commented Mar 4, 2024

Hi @TGTGamer , thanks for continuing to work on it. I've added a few review comments.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 5a5dcd4 and 80ea751.
Files selected for processing (1)
  • packages/schema/src/utils/ast-utils.ts (2 hunks)
Additional comments: 2
packages/schema/src/utils/ast-utils.ts (2)
  • 21-21: The addition of findNodeModulesFile from pkg-utils is a crucial part of enabling imports from node_modules. Ensure that pkg-utils is properly versioned and maintained to avoid potential future compatibility issues.
  • 98-113: The modifications to resolveImportUri introduce more robust handling of import paths, including support for node_modules paths. However, there are several points to consider:
  • The addition of the .zmodel extension (lines 100-101) assumes all imports should end with this extension. Confirm this assumption holds for all use cases.
  • The logic to determine if a path points to node_modules (lines 104-110) is clear. Ensure findNodeModulesFile gracefully handles cases where the node_modules directory or the specified module does not exist.
  • The final resolution of the path (line 113) is straightforward. Ensure that error handling is in place for cases where the resolved path does not exist or is inaccessible.
+ try {
+     const resolvedPath = Utils.resolvePath(dirUri, imp.path);
+     if (fs.existsSync(resolvedPath)) {
+         return resolvedPath;
+     } else {
+         throw new Error(`Resolved path does not exist: ${resolvedPath}`);
+     }
+ } catch (error) {
+     console.error(`Error resolving import path: ${error}`);
+     return undefined;
+ }
  • Consider using path.isAbsolute for checking absolute paths, as suggested by ymc9 in previous comments. This could simplify the checks for absolute paths on different platforms.
- && !imp.path.startsWith('/') // Respect absolute paths (Unix)
- && !/^[a-zA-Z]:\\/.test(imp.path) // Respect absolute paths (Windows)
+ && !path.isAbsolute(imp.path) // Respect absolute paths

@TGTGamer
Copy link
Contributor Author

Changes made. @ymc9 please review :)

@TGTGamer TGTGamer requested a review from ymc9 March 15, 2024 13:30
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 80ea751 and c8c0168.
Files selected for processing (2)
  • packages/schema/src/utils/ast-utils.ts (2 hunks)
  • packages/schema/src/utils/pkg-utils.ts (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/schema/src/utils/ast-utils.ts
Additional comments: 4
packages/schema/src/utils/pkg-utils.ts (4)
  • 8-9: The FindUp type definition is clear and well-documented. It effectively uses TypeScript's conditional types to return either a single string or an array of strings based on the generic parameter. This is a good use of TypeScript's advanced type features to create flexible and reusable utility types.
  • 17-19: The findUp function is well-documented and appears to be a versatile utility for finding files or directories by traversing up the directory tree. The use of generics to allow for returning either a single path or an array of paths is a smart design choice. However, it's important to ensure that this function is thoroughly tested, especially in edge cases such as symbolic links or filesystem permissions issues.
  • 40-52: The findNodeModulesFile function has been updated to use require.resolve for resolving module paths, which is a significant improvement over manual path construction. This leverages Node.js's own resolution logic, which is more reliable and handles edge cases better. The change addresses the comment from ymc9 regarding the use of require.resolve. This is a good example of incorporating feedback into the codebase.
  • 134-134: The findPackageJson function is marked as deprecated in favor of the findUp function. This is a good move towards simplifying the codebase and reducing redundancy. However, it's important to ensure that all references to findPackageJson throughout the project have been updated to use findUp instead. Additionally, consider adding a deprecation warning in the function body to alert developers who might still be using it.

ymc9
ymc9 previously approved these changes Mar 15, 2024
Copy link
Member

@ymc9 ymc9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now! The only remaining thing is the documentation of findNodeModulesFile is outdated. Please help update and the pr is good to merge!

Thank you!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between c8c0168 and 817e3e8.
Files selected for processing (1)
  • packages/schema/src/utils/pkg-utils.ts (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/schema/src/utils/pkg-utils.ts

@TGTGamer TGTGamer requested a review from ymc9 March 16, 2024 13:17
@ymc9 ymc9 merged commit f8f214d into zenstackhq:dev Mar 16, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants