Prepare Query doesn't work

I have…

  • Checked the logs, there’s nothing interesting there

I’m submitting a…

  • Bug report

Current behaviour

When an API request is made, the Prepare Query script is never executed. Even inserting an explicit disallow("Because") call in the script has no effect—the request is still processed and the target schema remains accessible.

Expected behaviour

According to documentation, Prepare Query should be called for all queried documents during API call

Self hosted with docker
Version: 7.21.0

How do you make the request? They are not executed when you make the call via the UI, because this could mess up everything

Via API, using POST /api/content/{appName}/{schema}/query

Which access token? I have tests for your case…

I’m using default client from Clients menu.
Refresh token like this:

body := strings.NewReader(url.Values{
		"grant_type":    {"client_credentials"},
		"client_id":     {c.clientID},
		"client_secret": {c.clientSecret},
		"scope":         {"squidex-api"},
	}.Encode())

	endpoint, err := url.JoinPath(c.baseAddr, "/identity-server/connect/token")
	if err != nil {
		return fmt.Errorf("can't join path: %w", err)
	}

What do you actually want to do? I am not sure if disallow actually works here.

Actually, I’m just trying to optimize this Query script:

// Return content schema names as we can't resolve it on backend
if(ctx.data.content.iv){
    getReferences(ctx.data.content.iv, (references)=>{
        ctx.data["content-types"].iv = JSON.stringify(
            references.map((ref)=>{
                return ref.SchemaId.Name
            })
        );
        replace();     
    })
}else{
    replace();     
}

As it’s runs for each document and it’s very slow. My plan was to collect all content ids and query references once.

Yeah, this does not work. You have to put the things in the context and then access them later.

See test:

    [Fact]
    public async Task Should_query_content_with_scripting_and_prepare_script()
    {
        var scripts = new SchemaScriptsDto
        {
            QueryPre = @$"
                    ctx.test = 17",
            Query = @$"
                    ctx.data.{TestEntityData.NumberField}.iv = ctx.test + 2;
                    replace()",
        };

        // STEP 1: Create a schema.
        await TestEntity.CreateSchemaAsync(_.Client.Schemas, schemaName, scripts);


        // STEP 2: Create content.
        var contents = _.Client.Contents<TestEntity, TestEntityData>(schemaName);

        var content = await contents.CreateAsync(
            new TestEntityData
            {
                Number = 99,
            },
            ContentCreateOptions.AsPublish);

        Assert.Equal(19, content.Data.Number);
    }

I see, Prepare Query can’t access all items. Maybe it’s possible to make QueryAll script then?

No, the problem is that the replace() only works on an indivudal item level. It should be able to access all items.