Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
push:
branches:
- main
env:
TELEMETRY_TRACKING_TOKEN: ${{ secrets.TELEMETRY_TRACKING_TOKEN }}
DO_NOT_TRACK: '1'
Comment on lines +8 to +10
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Scope the secret to the step that needs it.

Placing TELEMETRY_TRACKING_TOKEN at the workflow level exposes it to all steps, including third‑party actions. Scope it to the publish step; keep DO_NOT_TRACK at the top if you want global effect.

Apply:

-env:
-    TELEMETRY_TRACKING_TOKEN: ${{ secrets.TELEMETRY_TRACKING_TOKEN }}
-    DO_NOT_TRACK: '1'
+env:
+    DO_NOT_TRACK: '1'
@@
             - name: Publish packages
               run: pnpm run publish-all
               env:
                   NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+                  TELEMETRY_TRACKING_TOKEN: ${{ secrets.TELEMETRY_TRACKING_TOKEN }}

Also applies to: 48-52

🤖 Prompt for AI Agents
.github/workflows/publish-release.yml lines 8-10 (and similarly lines 48-52):
TELEMETRY_TRACKING_TOKEN is currently defined at the workflow/env level which
exposes it to all steps; remove TELEMETRY_TRACKING_TOKEN from the top-level env,
keep DO_NOT_TRACK there if you want global effect, and add
TELEMETRY_TRACKING_TOKEN as an env only on the publish step that needs it (set
to ${{ secrets.TELEMETRY_TRACKING_TOKEN }}), ensuring other steps and
third‑party actions cannot access the secret.


permissions:
contents: write
Expand Down
4 changes: 1 addition & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
{
"vitest.workspaceConfig": "./vitest.workspace.ts"
}
{}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zenstack-v3",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "ZenStack",
"packageManager": "pnpm@10.12.1",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"publisher": "zenstack",
"displayName": "ZenStack CLI",
"description": "FullStack database toolkit with built-in access control and automatic API generation.",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"type": "module",
"author": {
"name": "ZenStack Team"
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/test/init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import tmp from 'tmp';
import { describe, expect, it } from 'vitest';
import { runCli } from './utils';

describe('Cli init command tests', () => {
// skipping due to timeout during CI
describe.skip('Cli init command tests', () => {
it('should create a new project', () => {
const { name: workDir } = tmp.dirSync({ unsafeCleanup: true });
runCli('init', workDir);
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/test/migrate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ model User {
}
`;

describe('CLI migrate commands test', () => {
// skip due to timeout in CI
describe.skip('CLI migrate commands test', () => {
it('should generate a database with migrate dev', () => {
const workDir = createProject(model);
runCli('migrate dev --name init', workDir);
Expand Down
2 changes: 1 addition & 1 deletion packages/common-helpers/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/common-helpers",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "ZenStack Common Helpers",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/create-zenstack/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-zenstack",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "Create a new ZenStack project",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/dialects/sql.js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/kysely-sql-js",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "Kysely dialect for sql.js",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/eslint-config",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"type": "module",
"private": true,
"license": "MIT"
Expand Down
4 changes: 2 additions & 2 deletions packages/ide/vscode/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "zenstack-v3",
"publisher": "zenstack",
"version": "3.0.5",
"version": "3.0.6",
"displayName": "ZenStack V3 Language Tools",
"description": "VSCode extension for ZenStack (v3) ZModel language",
"private": true,
Expand Down Expand Up @@ -75,7 +75,7 @@
"grammars": [
{
"language": "zmodel-v3",
"scopeName": "source.zmodel",
"scopeName": "source.zmodel-v3",
"path": "./syntaxes/zmodel.tmLanguage.json"
Comment on lines +78 to 79
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Grammar scope rename: verify tmLanguage and references updated to match.

Ensure syntaxes/zmodel.tmLanguage.json uses the same scopeName and that no code still references "source.zmodel".

Run:

Expected:

  • Printed scopeName equals "source.zmodel-v3".
  • No matches for source.zmodel.

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Confirm tmLanguage scopeName matches
GRAMMAR_FILE="$(fd -a 'zmodel.tmLanguage.json' packages/ide/vscode | head -n1)"
echo "Grammar file: ${GRAMMAR_FILE}"
jq -r '.scopeName' "${GRAMMAR_FILE}"
test "$(jq -r '.scopeName' "${GRAMMAR_FILE}")" = "source.zmodel-v3"

# 2) Find remaining references to old scope
rg -nP '\bsource\.zmodel\b' -g '!**/node_modules/**'

Length of output: 219


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Finding zmodel grammar file(s)..."
find . -type f -name 'zmodel.tmLanguage.json'

echo -e "\nChecking scopeName in found file(s)..."
for f in $(find . -type f -name 'zmodel.tmLanguage.json'); do
  echo "$f: $(jq -r '.scopeName' "$f")"
done

echo -e "\nSearching for references to old scope 'source.zmodel'..."
rg -nP '\bsource\.zmodel\b' -g '!**/node_modules/**' || echo "No references found"

Length of output: 557


Missing tmLanguage grammar file

The path packages/ide/vscode/syntaxes/zmodel.tmLanguage.json referenced in package.json doesn’t exist; add the grammar file (or correct its path), then confirm its scopeName is "source.zmodel-v3" and that no code still references "source.zmodel".

🤖 Prompt for AI Agents
In packages/ide/vscode/package.json around lines 78-79, the extension references
a missing grammar file at ./syntaxes/zmodel.tmLanguage.json and a scopeName
"source.zmodel-v3"; add the missing zmodel.tmLanguage.json file at
packages/ide/vscode/syntaxes with scopeName set to "source.zmodel-v3" (or update
the path in package.json to the correct existing file), and then search the
codebase to replace any remaining references to "source.zmodel" with
"source.zmodel-v3" so all references and the package.json entry are consistent.

}
]
Expand Down
2 changes: 1 addition & 1 deletion packages/language/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/language",
"description": "ZenStack ZModel language specification",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"license": "MIT",
"author": "ZenStack Team",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/runtime",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "ZenStack Runtime",
"type": "module",
"scripts": {
Expand Down
25 changes: 16 additions & 9 deletions packages/runtime/src/client/crud/operations/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,26 @@ export class FindOperationHandler<Schema extends SchemaDef> extends BaseOperatio
// normalize args to strip `undefined` fields
const normalizedArgs = this.normalizeArgs(args);

const findOne = operation === 'findFirst' || operation === 'findUnique';

// parse args
const parsedArgs = validateArgs
? this.inputValidator.validateFindArgs(this.model, operation === 'findUnique', normalizedArgs)
: normalizedArgs;
let parsedArgs = validateArgs
? this.inputValidator.validateFindArgs(this.model, normalizedArgs, {
unique: operation === 'findUnique',
findOne,
})
: (normalizedArgs as FindArgs<Schema, GetModels<Schema>, true> | undefined);

if (findOne) {
// ensure "limit 1"
parsedArgs = parsedArgs ?? {};
parsedArgs.take = 1;
}

// run query
const result = await this.read(
this.client.$qb,
this.model,
parsedArgs as FindArgs<Schema, GetModels<Schema>, true>,
);
const result = await this.read(this.client.$qb, this.model, parsedArgs);

const finalResult = operation === 'findMany' ? result : (result[0] ?? null);
const finalResult = findOne ? (result[0] ?? null) : result;
return finalResult;
}
}
21 changes: 11 additions & 10 deletions packages/runtime/src/client/crud/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,11 @@ export class InputValidator<Schema extends SchemaDef> {

constructor(private readonly schema: Schema) {}

validateFindArgs(model: GetModels<Schema>, unique: boolean, args: unknown) {
return this.validate<FindArgs<Schema, GetModels<Schema>, true>, Parameters<typeof this.makeFindSchema>[1]>(
model,
'find',
{ unique },
(model, options) => this.makeFindSchema(model, options),
args,
);
validateFindArgs(model: GetModels<Schema>, args: unknown, options: { unique: boolean; findOne: boolean }) {
return this.validate<
FindArgs<Schema, GetModels<Schema>, true> | undefined,
Parameters<typeof this.makeFindSchema>[1]
>(model, 'find', options, (model, options) => this.makeFindSchema(model, options), args);
}

validateCreateArgs(model: GetModels<Schema>, args: unknown) {
Expand Down Expand Up @@ -196,7 +193,7 @@ export class InputValidator<Schema extends SchemaDef> {

// #region Find

private makeFindSchema(model: string, options: { unique: boolean }) {
private makeFindSchema(model: string, options: { unique: boolean; findOne: boolean }) {
const fields: Record<string, z.ZodSchema> = {};
const where = this.makeWhereSchema(model, options.unique);
if (options.unique) {
Expand All @@ -211,7 +208,11 @@ export class InputValidator<Schema extends SchemaDef> {

if (!options.unique) {
fields['skip'] = this.makeSkipSchema().optional();
fields['take'] = this.makeTakeSchema().optional();
if (options.findOne) {
fields['take'] = z.literal(1).optional();
} else {
fields['take'] = this.makeTakeSchema().optional();
}
fields['orderBy'] = this.orArray(this.makeOrderBySchema(model, true, false), true).optional();
fields['cursor'] = this.makeCursorSchema(model).optional();
fields['distinct'] = this.makeDistinctSchema(model).optional();
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/test/client-api/computed-fields.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ model User {
await expect(
db.user.findFirst({
orderBy: { upperName: 'desc' },
take: -1,
take: 1,
}),
).resolves.toMatchObject({
upperName: 'ALEX',
Expand Down
6 changes: 5 additions & 1 deletion packages/runtime/test/client-api/find.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import type { ClientContract } from '../../src/client';
import { NotFoundError } from '../../src/client/errors';
import { InputValidationError, NotFoundError } from '../../src/client/errors';
import { schema } from '../schemas/basic';
import { createClientSpecs } from './client-specs';
import { createPosts, createUser } from './utils';
Expand Down Expand Up @@ -54,6 +54,10 @@ describe.each(createClientSpecs(PG_DB_NAME))('Client find tests for $provider',
await expect(client.user.findMany({ take: 2 })).resolves.toHaveLength(2);
await expect(client.user.findMany({ take: 4 })).resolves.toHaveLength(3);

// findFirst's take must be 1
await expect(client.user.findFirst({ take: 2 })).rejects.toThrow(InputValidationError);
await expect(client.user.findFirst({ take: 1 })).toResolveTruthy();

// skip
await expect(client.user.findMany({ skip: 1 })).resolves.toHaveLength(2);
await expect(client.user.findMany({ skip: 2 })).resolves.toHaveLength(1);
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": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "ZenStack SDK",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/tanstack-query/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/tanstack-query",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "",
"main": "index.js",
"type": "module",
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": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "ZenStack Test Tools",
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/typescript-config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/typescript-config",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"private": true,
"license": "MIT"
}
2 changes: 1 addition & 1 deletion packages/vitest-config/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/vitest-config",
"type": "module",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"private": true,
"license": "MIT",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion packages/zod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/zod",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "",
"type": "module",
"main": "index.js",
Expand Down
2 changes: 1 addition & 1 deletion samples/blog/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sample-blog",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"description": "",
"main": "index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "e2e",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"private": true,
"type": "module",
"scripts": {
Expand Down
12 changes: 0 additions & 12 deletions vitest.base.config.ts

This file was deleted.

7 changes: 7 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
projects: ['packages/*'],
},
});
3 changes: 0 additions & 3 deletions vitest.workspace.ts

This file was deleted.