Skip to content

Commit

Permalink
merge dev to main (v1.11.0) (#1146)
Browse files Browse the repository at this point in the history
  • Loading branch information
ymc9 authored Mar 16, 2024
2 parents 336abf4 + f8f214d commit 599444c
Show file tree
Hide file tree
Showing 18 changed files with 152 additions and 30 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zenstack-monorepo",
"version": "1.10.3",
"version": "1.11.0",
"description": "",
"scripts": {
"build": "pnpm -r build",
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

group = "dev.zenstack"
version = "1.10.3"
version = "1.11.0"

repositories {
mavenCentral()
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jetbrains",
"version": "1.10.3",
"version": "1.11.0",
"displayName": "ZenStack JetBrains IDE Plugin",
"description": "ZenStack JetBrains IDE plugin",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/language/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/language",
"version": "1.10.3",
"version": "1.11.0",
"displayName": "ZenStack modeling language compiler",
"description": "ZenStack modeling language compiler",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/misc/redwood/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/redwood",
"displayName": "ZenStack RedwoodJS Integration",
"version": "1.10.3",
"version": "1.11.0",
"description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/openapi/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/openapi",
"displayName": "ZenStack Plugin and Runtime for OpenAPI",
"version": "1.10.3",
"version": "1.11.0",
"description": "ZenStack plugin and runtime supporting OpenAPI",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/swr/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/swr",
"displayName": "ZenStack plugin for generating SWR hooks",
"version": "1.10.3",
"version": "1.11.0",
"description": "ZenStack plugin for generating SWR hooks",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/tanstack-query/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/tanstack-query",
"displayName": "ZenStack plugin for generating tanstack-query hooks",
"version": "1.10.3",
"version": "1.11.0",
"description": "ZenStack plugin for generating tanstack-query hooks",
"main": "index.js",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/trpc/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/trpc",
"displayName": "ZenStack plugin for tRPC",
"version": "1.10.3",
"version": "1.11.0",
"description": "ZenStack plugin for tRPC",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/runtime",
"displayName": "ZenStack Runtime Library",
"version": "1.10.3",
"version": "1.11.0",
"description": "Runtime of ZenStack for both client-side and server-side environments.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"publisher": "zenstack",
"displayName": "ZenStack Language Tools",
"description": "Build scalable web apps with minimum code by defining authorization and validation rules inside the data schema that closer to the database",
"version": "1.10.3",
"version": "1.11.0",
"author": {
"name": "ZenStack Team"
},
Expand Down
22 changes: 15 additions & 7 deletions packages/schema/src/utils/ast-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
import { isFromStdlib } from '@zenstackhq/sdk';
import { AstNode, getDocument, LangiumDocuments, Mutable } from 'langium';
import { URI, Utils } from 'vscode-uri';
import { findNodeModulesFile } from './pkg-utils';
import {isAbsolute} from 'node:path'

export function extractDataModelsWithAllowRules(model: Model): DataModel[] {
return model.declarations.filter(
Expand Down Expand Up @@ -94,15 +96,21 @@ export function getDataModelFieldReference(expr: Expression): DataModelField | u
}

export function resolveImportUri(imp: ModelImport): URI | undefined {
if (imp.path === undefined || imp.path.length === 0) {
return undefined;
if (!imp.path) return undefined; // This will return true if imp.path is undefined, null, or an empty string ("").

if (!imp.path.endsWith('.zmodel')) {
imp.path += '.zmodel';
}
const dirUri = Utils.dirname(getDocument(imp).uri);
let grammarPath = imp.path;
if (!grammarPath.endsWith('.zmodel')) {
grammarPath += '.zmodel';

if (
!imp.path.startsWith('.') // Respect relative paths
&& !isAbsolute(imp.path) // Respect Absolute paths
) {
imp.path = findNodeModulesFile(imp.path) ?? imp.path;
}
return Utils.resolvePath(dirUri, grammarPath);

const dirUri = Utils.dirname(getDocument(imp).uri);
return Utils.resolvePath(dirUri, imp.path);
}

export function resolveTransitiveImports(documents: LangiumDocuments, model: Model): Model[] {
Expand Down
36 changes: 30 additions & 6 deletions packages/schema/src/utils/pkg-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ import { execSync } from './exec-utils';
export type PackageManagers = 'npm' | 'yarn' | 'pnpm';

/**
* A type named FindUp that takes a type parameter e which extends boolean.
* If e extends true, it returns a union type of string[] or undefined.
* A type named FindUp that takes a type parameter e which extends boolean.
* If e extends true, it returns a union type of string[] or undefined.
* If e does not extend true, it returns a union type of string or undefined.
*
* @export
* @template e A type parameter that extends boolean
*/
export type FindUp<e extends boolean> = e extends true ? string[] | undefined : string | undefined
/**
* Find and return file paths by searching parent directories based on the given names list and current working directory (cwd) path.
* Optionally return a single path or multiple paths.
* If multiple allowed, return all paths found.
* Find and return file paths by searching parent directories based on the given names list and current working directory (cwd) path.
* Optionally return a single path or multiple paths.
* If multiple allowed, return all paths found.
* If no paths are found, return undefined.
*
* @export
Expand All @@ -37,6 +37,30 @@ export function findUp<e extends boolean = false>(names: string[], cwd: string =
return findUp(names, up, multiple, result);
}


/**
* Find a Node module/file given its name in a specific directory, with a fallback to the current working directory.
* If the name is empty, return undefined.
* Try to resolve the module/file using require.resolve with the specified directory as the starting point.
* Return the resolved path if successful, otherwise return undefined.
*
* @export
* @param {string} name The name of the module/file to find
* @param {string} [cwd=process.cwd()]
* @returns {*} Finds a specified module or file using require.resolve starting from a specified directory path, or the current working directory if not provided.
*/
export function findNodeModulesFile(name: string, cwd: string = process.cwd()) {
if (!name) return undefined;
try {
// Use require.resolve to find the module/file. The paths option allows specifying the directory to start from.
const resolvedPath = require.resolve(name, { paths: [cwd] })
return resolvedPath
} catch (error) {
// If require.resolve fails to find the module/file, it will throw an error.
return undefined
}
}

function getPackageManager(projectPath = '.'): PackageManagers {
const lockFile = findUp(['yarn.lock', 'pnpm-lock.yaml', 'package-lock.json'], projectPath);

Expand Down Expand Up @@ -106,7 +130,7 @@ export function ensurePackage(
}

/**
* A function that searches for the nearest package.json file starting from the provided search path or the current working directory if no search path is provided.
* A function that searches for the nearest package.json file starting from the provided search path or the current working directory if no search path is provided.
* It iterates through the directory structure going one level up at a time until it finds a package.json file. If no package.json file is found, it returns undefined.
* @deprecated Use findUp instead @see findUp
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/sdk",
"version": "1.10.3",
"version": "1.11.0",
"description": "ZenStack plugin development SDK",
"main": "index.js",
"scripts": {
Expand Down
9 changes: 6 additions & 3 deletions packages/sdk/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,14 @@ export function isIdField(field: DataModelField) {
return true;
}

// NOTE: we have to use name to match fields because the fields
// may be inherited from an abstract base and have cloned identities

const model = field.$container as DataModel;

// model-level @@id attribute with a list of fields
const modelLevelIds = getModelIdFields(model);
if (modelLevelIds.includes(field)) {
if (modelLevelIds.map((f) => f.name).includes(field.name)) {
return true;
}

Expand All @@ -234,12 +237,12 @@ export function isIdField(field: DataModelField) {
// then, the first field with @unique can be used as id
const firstUniqueField = model.fields.find((f) => hasAttribute(f, '@unique'));
if (firstUniqueField) {
return firstUniqueField === field;
return firstUniqueField.name === field.name;
}

// last, the first model level @@unique can be used as id
const modelLevelUnique = getModelUniqueFields(model);
if (modelLevelUnique.includes(field)) {
if (modelLevelUnique.map((f) => f.name).includes(field.name)) {
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/server",
"version": "1.10.3",
"version": "1.11.0",
"displayName": "ZenStack Server-side Adapters",
"description": "ZenStack server-side adapters",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/testtools/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/testtools",
"version": "1.10.3",
"version": "1.11.0",
"description": "ZenStack Test Tools",
"main": "index.js",
"private": true,
Expand Down
87 changes: 87 additions & 0 deletions tests/integration/tests/regression/issue-1129.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { createPostgresDb, dropPostgresDb, loadSchema } from '@zenstackhq/testtools';

describe('Regression for issue 1129', () => {
it('regression', async () => {
let prisma;
const dbUrl = await createPostgresDb('regression-issue-1129');

try {
const r = await loadSchema(
`
model Relation1 {
id String @id @default(cuid())
field1 String
concrete Concrete[]
@@allow('all', true)
}
model Relation2 {
id String @id @default(cuid())
field2 String
concrete Concrete[]
@@allow('all', true)
}
abstract model WithRelation1 {
relation1Id String
relation1 Relation1 @relation(fields: [relation1Id], references: [id])
}
abstract model WithRelation2 {
relation2Id String
relation2 Relation2 @relation(fields: [relation2Id], references: [id])
}
model Concrete extends WithRelation1, WithRelation2 {
concreteField String
@@id([relation1Id, relation2Id])
@@allow('all', true)
}
`,
{ provider: 'postgresql', dbUrl }
);

prisma = r.prisma;
const db = r.enhance();

await db.$transaction(async (tx: any) => {
await tx.relation2.createMany({
data: [
{
id: 'relation2Id1',
field2: 'field2Value1',
},
{
id: 'relation2Id2',
field2: 'field2Value2',
},
],
});

await tx.relation1.create({
data: {
field1: 'field1Value',
concrete: {
createMany: {
data: [
{
concreteField: 'concreteFieldValue1',
relation2Id: 'relation2Id1',
},
{
concreteField: 'concreteFieldValue2',
relation2Id: 'relation2Id2',
},
],
},
},
},
});
});
} finally {
if (prisma) {
await prisma.$disconnect();
}
await dropPostgresDb('regression-issue-1129');
}
});
});

0 comments on commit 599444c

Please sign in to comment.