@opencraw/azure-durable 0.0.47 → 0.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/caller-access/caller-access.policy.d.ts +28 -0
- package/dist/caller-access/index.d.ts +3 -0
- package/dist/callout-resume/callout-event.mapper.d.ts +30 -0
- package/dist/callout-resume/callout-ticket.algorithm.d.ts +36 -0
- package/dist/callout-resume/index.d.ts +5 -0
- package/dist/callout-resume/resolve-callout.handler.d.ts +17 -0
- package/dist/crawl-run/crawl-job.model.d.ts +52 -0
- package/dist/crawl-run/crawl-job.validator.d.ts +11 -0
- package/dist/crawl-run/crawl-orchestration.use-case.d.ts +22 -0
- package/dist/crawl-run/crawl-request.validator.d.ts +25 -0
- package/dist/crawl-run/index.d.ts +8 -0
- package/dist/crawl-run/run-recipe.use-case.d.ts +18 -0
- package/dist/crawl-run/start-crawl.handler.d.ts +18 -0
- package/dist/host-options/host-options.config.d.ts +100 -0
- package/dist/host-options/index.d.ts +3 -0
- package/dist/http-reply/http-reply.mapper.d.ts +24 -0
- package/dist/http-reply/index.d.ts +2 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.esm.js +428 -1157
- package/dist/open-craw-host/host-json.validator.d.ts +11 -0
- package/dist/open-craw-host/index.d.ts +4 -0
- package/dist/open-craw-host/register-open-craw.use-case.d.ts +48 -0
- package/dist/recipe-authoring/authoring-server.use-case.d.ts +13 -0
- package/dist/recipe-authoring/authoring-tools.use-case.d.ts +96 -0
- package/dist/recipe-authoring/index.d.ts +5 -0
- package/dist/recipe-authoring/mcp-endpoint.handler.d.ts +18 -0
- package/dist/recipe-authoring/promote.handler.d.ts +13 -0
- package/dist/recipe-store/blob-recipe.store.d.ts +20 -0
- package/dist/recipe-store/find-recipes.use-case.d.ts +13 -0
- package/dist/recipe-store/index.d.ts +7 -0
- package/dist/recipe-store/memory-recipe.store.d.ts +12 -0
- package/dist/recipe-store/recipe-store.contract.d.ts +28 -0
- package/dist/recipe-store/recipe-store.error.d.ts +6 -0
- package/dist/result-store/blob-result.store.d.ts +18 -0
- package/dist/result-store/index.d.ts +6 -0
- package/dist/result-store/result-packing.policy.d.ts +22 -0
- package/dist/result-store/result-store.contract.d.ts +13 -0
- package/dist/src/crawl-run/crawl-request.validator.d.ts +2 -2
- package/dist/src/worker-pools/item-request.validator.d.ts +1 -1
- package/dist/worker-pools/index.d.ts +10 -0
- package/dist/worker-pools/item-job.validator.d.ts +10 -0
- package/dist/worker-pools/item-orchestration.use-case.d.ts +14 -0
- package/dist/worker-pools/item-request.validator.d.ts +35 -0
- package/dist/worker-pools/job.handler.d.ts +14 -0
- package/dist/worker-pools/pool-job.model.d.ts +43 -0
- package/dist/worker-pools/submit-item.handler.d.ts +20 -0
- package/dist/worker-pools/windows-cap.policy.d.ts +12 -0
- package/dist/worker-pools/worker-pools.store.d.ts +58 -0
- package/package.json +10 -38
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { HttpRequest } from '@azure/functions';
|
|
2
|
+
/** Who is calling and where their recipes may go. */
|
|
3
|
+
export interface CallerAccess {
|
|
4
|
+
/** `undefined` when the host does not tell callers apart. */
|
|
5
|
+
caller?: string;
|
|
6
|
+
allowedHosts: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
export interface CallerRules {
|
|
9
|
+
allowedHosts: readonly string[] | ((caller: string | undefined) => readonly string[] | undefined);
|
|
10
|
+
identify?: (request: HttpRequest) => string | undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Resolves the caller of a request and the hosts its recipes may reach.
|
|
14
|
+
*
|
|
15
|
+
* @param request - The request.
|
|
16
|
+
* @param rules - The host's `identify` and `allowedHosts`.
|
|
17
|
+
* @returns The access, or `undefined` when this caller may run nothing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function callerAccess(request: HttpRequest, rules: CallerRules): CallerAccess | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* The key a caller's pools and jobs live under, so two callers never share a pool.
|
|
22
|
+
*
|
|
23
|
+
* @param access - The caller.
|
|
24
|
+
* @param crawlId - The job.
|
|
25
|
+
* @returns The key.
|
|
26
|
+
*/
|
|
27
|
+
export declare function poolKey(access: Pick<CallerAccess, 'caller'>, crawlId: string): string;
|
|
28
|
+
//# sourceMappingURL=caller-access.policy.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { HostSettings } from '../host-options';
|
|
2
|
+
/**
|
|
3
|
+
* The name of the external event a posted-back result is raised as. The call's idempotency key is the
|
|
4
|
+
* same for the same call anywhere in the job, so the recipe's index keeps two recipes that make an
|
|
5
|
+
* identical call apart.
|
|
6
|
+
*
|
|
7
|
+
* @param index - The input recipe of the job.
|
|
8
|
+
* @param key - The call's idempotency key.
|
|
9
|
+
* @returns The event name.
|
|
10
|
+
*/
|
|
11
|
+
export declare function calloutEventName(index: number, key: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Where a handler posts a result, given the URL the job was started at.
|
|
14
|
+
*
|
|
15
|
+
* `publicUrl` wins when the host sets it (behind a proxy or a custom domain the request does not show);
|
|
16
|
+
* otherwise it is the start URL without its last path segment, which is where `/crawl` and
|
|
17
|
+
* `/callouts/{token}/resolve` are siblings.
|
|
18
|
+
*
|
|
19
|
+
* @param startUrl - The URL of the `/crawl` request.
|
|
20
|
+
* @param settings - The host settings.
|
|
21
|
+
* @returns The base all callback URLs start with, without a trailing slash.
|
|
22
|
+
*/
|
|
23
|
+
export declare function callbackBaseOf(startUrl: string, settings: Pick<HostSettings, 'callouts'>): string;
|
|
24
|
+
/**
|
|
25
|
+
* @param base - What `callbackBaseOf` returned.
|
|
26
|
+
* @param token - The signed ticket.
|
|
27
|
+
* @returns The URL a handler posts its `CalloutResolution` to.
|
|
28
|
+
*/
|
|
29
|
+
export declare function callbackUrl(base: string, token: string): string;
|
|
30
|
+
//# sourceMappingURL=callout-event.mapper.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** What a resume token says: which call of which recipe of which job it may settle, and until when. */
|
|
2
|
+
export interface CalloutTicket {
|
|
3
|
+
instanceId: string;
|
|
4
|
+
/** The input recipe of the job the call belongs to. */
|
|
5
|
+
index: number;
|
|
6
|
+
/** The call's idempotency key. */
|
|
7
|
+
key: string;
|
|
8
|
+
/** Epoch milliseconds. */
|
|
9
|
+
expiresAt: number;
|
|
10
|
+
}
|
|
11
|
+
export type TicketReading = {
|
|
12
|
+
ok: true;
|
|
13
|
+
ticket: CalloutTicket;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
reason: 'malformed' | 'signature' | 'expired';
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The token a handler posts its result back with. It is the ticket and an HMAC of it, so the host holds no
|
|
20
|
+
* state for it: any instance of the Function App can check it.
|
|
21
|
+
*
|
|
22
|
+
* @param secret - The host's signing key.
|
|
23
|
+
* @param ticket - What the token lets its holder do.
|
|
24
|
+
* @returns A URL-safe token.
|
|
25
|
+
*/
|
|
26
|
+
export declare function signCalloutTicket(secret: string, ticket: CalloutTicket): string;
|
|
27
|
+
/**
|
|
28
|
+
* Checks a token and reads the ticket in it.
|
|
29
|
+
*
|
|
30
|
+
* @param secret - The host's signing key.
|
|
31
|
+
* @param token - What was posted to.
|
|
32
|
+
* @param now - The current time, epoch milliseconds.
|
|
33
|
+
* @returns The ticket, or why the token is not good.
|
|
34
|
+
*/
|
|
35
|
+
export declare function readCalloutTicket(secret: string, token: string, now: number): TicketReading;
|
|
36
|
+
//# sourceMappingURL=callout-ticket.algorithm.d.ts.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { signCalloutTicket, readCalloutTicket } from './callout-ticket.algorithm';
|
|
2
|
+
export type { CalloutTicket, TicketReading } from './callout-ticket.algorithm';
|
|
3
|
+
export { calloutEventName, callbackBaseOf, callbackUrl } from './callout-event.mapper';
|
|
4
|
+
export { resolveCallout } from './resolve-callout.handler';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { HttpRequest, HttpResponseInit } from '@azure/functions';
|
|
2
|
+
import type { DurableClient } from 'durable-functions';
|
|
3
|
+
import type { HostSettings } from '../host-options';
|
|
4
|
+
/**
|
|
5
|
+
* `POST /callouts/{token}/resolve`: a handler that answered `pending` posts the result of the call here.
|
|
6
|
+
* The token in the path is the credential (it is a signed ticket for that one call), so the route does
|
|
7
|
+
* not ask for a function key. The result is raised to the waiting job as an external event; a second post
|
|
8
|
+
* for a call that was already settled finds nobody waiting and is refused.
|
|
9
|
+
*
|
|
10
|
+
* @param request - The request.
|
|
11
|
+
* @param client - The Durable client.
|
|
12
|
+
* @param settings - The host settings.
|
|
13
|
+
* @param now - The current time, epoch milliseconds.
|
|
14
|
+
* @returns 202 when the result was handed to the job, or the problem.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveCallout(request: HttpRequest, client: DurableClient, settings: HostSettings, now?: number): Promise<HttpResponseInit>;
|
|
17
|
+
//# sourceMappingURL=resolve-callout.handler.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { CalloutResolution, OutputRecord, ParkedCallout, RecipeReport } from '@opencraw/core';
|
|
2
|
+
/** What a `/crawl` orchestration runs: written by the starter, never by the caller. */
|
|
3
|
+
export interface CrawlJob {
|
|
4
|
+
caller?: string;
|
|
5
|
+
allowedHosts: string[];
|
|
6
|
+
output: unknown;
|
|
7
|
+
inputs: unknown[];
|
|
8
|
+
dedupe?: 'recipe' | 'off';
|
|
9
|
+
/** Where handlers post results back (`https://app/api`): set by the starter when the host takes posted-back results. */
|
|
10
|
+
callbackBase?: string;
|
|
11
|
+
}
|
|
12
|
+
/** One input recipe of a job, run by one activity. */
|
|
13
|
+
export interface RecipeTask {
|
|
14
|
+
allowedHosts: string[];
|
|
15
|
+
output: unknown;
|
|
16
|
+
input: unknown;
|
|
17
|
+
dedupe?: 'recipe' | 'off';
|
|
18
|
+
/** Where its records go when too large to return: `<instance>/<index>.jsonl`. */
|
|
19
|
+
resultName: string;
|
|
20
|
+
/** The job's instance and this recipe's index in it: what a resume token names. */
|
|
21
|
+
instanceId: string;
|
|
22
|
+
index: number;
|
|
23
|
+
callbackBase?: string;
|
|
24
|
+
/** Results of calls that parked on an earlier run of this recipe, by idempotency key. */
|
|
25
|
+
resolutions?: Record<string, CalloutResolution>;
|
|
26
|
+
}
|
|
27
|
+
export interface RecipeTaskResult {
|
|
28
|
+
/** One per run: a recipe with a `matrix` runs once per variant. */
|
|
29
|
+
reports: RecipeReport[];
|
|
30
|
+
records?: OutputRecord[];
|
|
31
|
+
resultUrl?: string;
|
|
32
|
+
/** Set when calls are waiting for their results to be posted back: the run stopped, and this is what it waits for. */
|
|
33
|
+
parked?: ParkedCallout[];
|
|
34
|
+
}
|
|
35
|
+
/** What a `/crawl` orchestration returns. */
|
|
36
|
+
export interface CrawlResult {
|
|
37
|
+
/** One report per input recipe run (a matrix recipe: per variant), in the order given. */
|
|
38
|
+
recipes: RecipeReport[];
|
|
39
|
+
/** The records returned inline. */
|
|
40
|
+
records: OutputRecord[];
|
|
41
|
+
/** Links to the records too large to return inline, one per recipe that had them. */
|
|
42
|
+
results: string[];
|
|
43
|
+
}
|
|
44
|
+
/** The orchestration's custom status while it runs. */
|
|
45
|
+
export interface CrawlProgress {
|
|
46
|
+
recipes: number;
|
|
47
|
+
recipesDone: number;
|
|
48
|
+
records: number;
|
|
49
|
+
/** Recipes waiting for a posted-back result. Present only when the host takes them. */
|
|
50
|
+
recipesWaiting?: number;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=crawl-job.model.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CrawlJob } from './crawl-job.model';
|
|
2
|
+
/**
|
|
3
|
+
* Checks a `/crawl` orchestration's input as it comes back out of the task
|
|
4
|
+
* hub: an instance started before a deploy resumes against the new code.
|
|
5
|
+
*
|
|
6
|
+
* @param raw - The stored input.
|
|
7
|
+
* @returns The job.
|
|
8
|
+
* @throws ZodError when it is not one.
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseCrawlJob(raw: unknown): CrawlJob;
|
|
11
|
+
//# sourceMappingURL=crawl-job.validator.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { TypedActivity } from '@mnci/az-durable';
|
|
2
|
+
import type { OrchestrationContext, Task } from 'durable-functions';
|
|
3
|
+
import type { CrawlJob, CrawlResult, RecipeTask, RecipeTaskResult } from './crawl-job.model';
|
|
4
|
+
export interface CrawlOrchestratorOptions {
|
|
5
|
+
/** How long a recipe waits for the results of parked calls before it fails. Only used when a call parks. */
|
|
6
|
+
waitMs?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The `/crawl` orchestration: one activity per input recipe, all at once;
|
|
10
|
+
* the custom status counts recipes and records as each one finishes.
|
|
11
|
+
*
|
|
12
|
+
* A recipe whose hooks answered `pending` and will post their results back stops its activity with
|
|
13
|
+
* `parked` calls. The orchestration then waits for one external event per call (and a timer, so a
|
|
14
|
+
* handler that never answers fails the recipe, not the job) and runs the recipe again with the results
|
|
15
|
+
* so far: calls that have a result return it without being made again.
|
|
16
|
+
*
|
|
17
|
+
* @param runRecipe - The activity that runs one recipe.
|
|
18
|
+
* @param options - How long to wait for posted-back results.
|
|
19
|
+
* @returns The orchestrator body.
|
|
20
|
+
*/
|
|
21
|
+
export declare function crawlOrchestrator(runRecipe: TypedActivity<RecipeTask, RecipeTaskResult>, options?: CrawlOrchestratorOptions): (context: OrchestrationContext, job: CrawlJob) => Generator<Task, CrawlResult, unknown>;
|
|
22
|
+
//# sourceMappingURL=crawl-orchestration.use-case.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** A `/crawl` body: the recipes themselves, or the name and version of a stored set. */
|
|
3
|
+
export declare const crawlRequestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
4
|
+
output: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
5
|
+
inputs: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
6
|
+
options: z.ZodOptional<z.ZodObject<{
|
|
7
|
+
dedupe: z.ZodOptional<z.ZodEnum<{
|
|
8
|
+
off: "off";
|
|
9
|
+
recipe: "recipe";
|
|
10
|
+
}>>;
|
|
11
|
+
}, z.core.$strict>>;
|
|
12
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
13
|
+
recipe: z.ZodObject<{
|
|
14
|
+
name: z.ZodString;
|
|
15
|
+
version: z.ZodString;
|
|
16
|
+
}, z.core.$strict>;
|
|
17
|
+
options: z.ZodOptional<z.ZodObject<{
|
|
18
|
+
dedupe: z.ZodOptional<z.ZodEnum<{
|
|
19
|
+
off: "off";
|
|
20
|
+
recipe: "recipe";
|
|
21
|
+
}>>;
|
|
22
|
+
}, z.core.$strict>>;
|
|
23
|
+
}, z.core.$strict>]>;
|
|
24
|
+
export type CrawlRequest = z.infer<typeof crawlRequestSchema>;
|
|
25
|
+
//# sourceMappingURL=crawl-request.validator.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { crawlOrchestrator } from './crawl-orchestration.use-case';
|
|
2
|
+
export { runRecipeTask } from './run-recipe.use-case';
|
|
3
|
+
export { startCrawl } from './start-crawl.handler';
|
|
4
|
+
export { crawlRequestSchema } from './crawl-request.validator';
|
|
5
|
+
export type { CrawlRequest } from './crawl-request.validator';
|
|
6
|
+
export type { CrawlJob, CrawlResult, CrawlProgress, RecipeTask, RecipeTaskResult } from './crawl-job.model';
|
|
7
|
+
export { parseCrawlJob } from './crawl-job.validator';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HostSettings } from '../host-options';
|
|
2
|
+
import type { RecipeTask, RecipeTaskResult } from './crawl-job.model';
|
|
3
|
+
/**
|
|
4
|
+
* The `/crawl` activity: one input recipe, on a crawler of its own, limited
|
|
5
|
+
* to the caller's hosts. A recipe that fails is reported, not thrown: the
|
|
6
|
+
* orchestration still gathers the others.
|
|
7
|
+
*
|
|
8
|
+
* When the host takes posted-back results, a hook that answers `pending` parks its call instead of
|
|
9
|
+
* being polled: the run stops and the result says which calls it is waiting for (`parked`), with no
|
|
10
|
+
* reports, because the orchestration runs the recipe again once they have arrived.
|
|
11
|
+
*
|
|
12
|
+
* @param settings - The host settings.
|
|
13
|
+
* @param task - The recipe and where its records go.
|
|
14
|
+
* @param now - The current time, epoch milliseconds (for the token expiry).
|
|
15
|
+
* @returns Its reports (one per matrix variant) and records (or their link), or what it waits for.
|
|
16
|
+
*/
|
|
17
|
+
export declare function runRecipeTask(settings: HostSettings, task: RecipeTask, now?: number): Promise<RecipeTaskResult>;
|
|
18
|
+
//# sourceMappingURL=run-recipe.use-case.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HttpRequest, HttpResponse, HttpResponseInit } from '@azure/functions';
|
|
2
|
+
import type { TypedOrchestration } from '@mnci/az-durable';
|
|
3
|
+
import type { DurableClient } from 'durable-functions';
|
|
4
|
+
import type { HostSettings } from '../host-options';
|
|
5
|
+
import type { CrawlJob, CrawlResult } from './crawl-job.model';
|
|
6
|
+
/**
|
|
7
|
+
* `POST /crawl`: checks the caller and the recipes, then starts the
|
|
8
|
+
* orchestration. Recipes that do not load are a 400 before anything is
|
|
9
|
+
* queued.
|
|
10
|
+
*
|
|
11
|
+
* @param request - The request.
|
|
12
|
+
* @param client - The Durable client.
|
|
13
|
+
* @param settings - The host settings.
|
|
14
|
+
* @param orchestration - The `/crawl` orchestration.
|
|
15
|
+
* @returns 202 with the Durable status URLs, or the problem.
|
|
16
|
+
*/
|
|
17
|
+
export declare function startCrawl(request: HttpRequest, client: DurableClient, settings: HostSettings, orchestration: TypedOrchestration<CrawlJob, CrawlResult>): Promise<HttpResponse | HttpResponseInit>;
|
|
18
|
+
//# sourceMappingURL=start-crawl.handler.d.ts.map
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { HttpRequest } from '@azure/functions';
|
|
2
|
+
import type { AccessConfig, AccessPlugin, BrowserSessionConfig, CaptchaSolver, CrawlOptions, HookMap, WindowsPolicy } from '@opencraw/core';
|
|
3
|
+
import type { RecipeStore } from '../recipe-store';
|
|
4
|
+
import type { ResultStore } from '../result-store';
|
|
5
|
+
/** How the host is set up: everything that is code or a secret lives here, never in a request. */
|
|
6
|
+
export interface OpenCrawHostOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The hosts a caller's recipes may reach (`example.com`, `*.example.com`,
|
|
9
|
+
* `host:port`, `*`). A list applies to every caller; a function decides per
|
|
10
|
+
* caller, and a caller it returns nothing for is refused (403).
|
|
11
|
+
*/
|
|
12
|
+
allowedHosts: readonly string[] | ((caller: string | undefined) => readonly string[] | undefined);
|
|
13
|
+
/**
|
|
14
|
+
* Who is calling, from the request: an Entra ID principal (App Service
|
|
15
|
+
* authentication sets `x-ms-client-principal-name`), a key name, a header
|
|
16
|
+
* your gateway sets. Only trust a header something in front of the app
|
|
17
|
+
* sets and callers cannot. Default: nobody in particular.
|
|
18
|
+
*/
|
|
19
|
+
identify?: (request: HttpRequest) => string | undefined;
|
|
20
|
+
/** Named recipes: what `/jobs` items and `/crawl` by name run. */
|
|
21
|
+
recipes?: RecipeStore;
|
|
22
|
+
/** Where results too large to return inline go. Without one, every result is returned inline. */
|
|
23
|
+
results?: ResultStore;
|
|
24
|
+
/** Results larger than this (as JSON) go to `results`. Default 256 KiB. */
|
|
25
|
+
inlineLimitBytes?: number;
|
|
26
|
+
hooks?: HookMap;
|
|
27
|
+
/** A fresh set per crawler: a crawler closes its solvers when it closes. */
|
|
28
|
+
captchaSolvers?: () => CaptchaSolver[];
|
|
29
|
+
access?: AccessConfig;
|
|
30
|
+
accessPlugins?: AccessPlugin[];
|
|
31
|
+
browser?: BrowserSessionConfig;
|
|
32
|
+
/** Worker pools: one per caller and crawl id. */
|
|
33
|
+
pools?: PoolSettings;
|
|
34
|
+
/**
|
|
35
|
+
* The recipe-authoring MCP endpoint, `/mcp`: `true`, or its sample limits.
|
|
36
|
+
* Off by default. It refuses to start without authentication.
|
|
37
|
+
*/
|
|
38
|
+
mcp?: boolean | McpSettings;
|
|
39
|
+
/** Who may promote a draft to production (`POST /recipes/{name}/{version}/promote`). Default: nobody. */
|
|
40
|
+
canPromote?: (caller: string | undefined) => boolean;
|
|
41
|
+
/** Default `function`: a function key is needed. `anonymous` only behind something that authenticates. */
|
|
42
|
+
authLevel?: 'anonymous' | 'function' | 'admin';
|
|
43
|
+
/** Prepended to every route: `'opencraw'` gives `/api/opencraw/crawl`. Default none. */
|
|
44
|
+
routePrefix?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Lets a hook that answers `pending` post its result back (`POST /callouts/{token}/resolve`) instead of
|
|
47
|
+
* being asked again. Off by default: a pending hook is then polled inside the activity.
|
|
48
|
+
*/
|
|
49
|
+
callouts?: CalloutSettings;
|
|
50
|
+
}
|
|
51
|
+
export interface CalloutSettings {
|
|
52
|
+
/** The name of the environment variable holding the key that signs resume tokens. A secret: never in code or a recipe. */
|
|
53
|
+
signingKeyEnv: string;
|
|
54
|
+
/** The base URL handlers post to (`https://app.example.com/api`), when the request URL is not it (a proxy, a custom domain). Default: derived from the request that started the job. */
|
|
55
|
+
publicUrl?: string;
|
|
56
|
+
/** How long a job waits for a posted-back result before the recipe fails. Default 1 hour. */
|
|
57
|
+
waitMs?: number;
|
|
58
|
+
}
|
|
59
|
+
export interface McpSettings {
|
|
60
|
+
/** A sample run (`run` without `full`) stops after this many records per input recipe. Default 20. */
|
|
61
|
+
sampleRecords?: number;
|
|
62
|
+
/** And after this long, whatever it has by then. Default 60 seconds: MCP clients time out tool calls. */
|
|
63
|
+
sampleMs?: number;
|
|
64
|
+
}
|
|
65
|
+
export interface PoolSettings {
|
|
66
|
+
/** A pool with no item for this long closes. Default 10 minutes. */
|
|
67
|
+
idleTtlMs?: number;
|
|
68
|
+
/** The windows policy a job gets when its request names none. Default `{ min: 1, max: 4, grow: { after: 5 }, idle: { afterMs: 60000 } }`. */
|
|
69
|
+
windows?: WindowsPolicy;
|
|
70
|
+
/** No pool gets more windows than this, whatever a job asks. Default 8. */
|
|
71
|
+
maxWindows?: number;
|
|
72
|
+
}
|
|
73
|
+
/** The options with their defaults. */
|
|
74
|
+
export interface HostSettings extends Omit<OpenCrawHostOptions, 'pools' | 'inlineLimitBytes' | 'routePrefix' | 'authLevel' | 'mcp' | 'canPromote' | 'callouts'> {
|
|
75
|
+
inlineLimitBytes: number;
|
|
76
|
+
routePrefix: string;
|
|
77
|
+
authLevel: 'anonymous' | 'function' | 'admin';
|
|
78
|
+
pools: Required<PoolSettings>;
|
|
79
|
+
/** `undefined` when the endpoint is off. */
|
|
80
|
+
mcp?: Required<McpSettings>;
|
|
81
|
+
canPromote: (caller: string | undefined) => boolean;
|
|
82
|
+
/** `undefined` when posted-back results are off. */
|
|
83
|
+
callouts?: Required<Pick<CalloutSettings, 'signingKeyEnv' | 'waitMs'>> & Pick<CalloutSettings, 'publicUrl'>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* @param options - As given.
|
|
87
|
+
* @returns The options with their defaults.
|
|
88
|
+
* @throws Error when `allowedHosts` is an empty list (a host that may reach nothing runs nothing), or the MCP endpoint would be open to anyone.
|
|
89
|
+
*/
|
|
90
|
+
export declare function resolveHostOptions(options: OpenCrawHostOptions): HostSettings;
|
|
91
|
+
/**
|
|
92
|
+
* What a crawler for one caller is created with: the host's code and
|
|
93
|
+
* secrets, and the caller's hosts.
|
|
94
|
+
*
|
|
95
|
+
* @param settings - The host settings.
|
|
96
|
+
* @param allowedHosts - The caller's hosts.
|
|
97
|
+
* @returns Crawl options, without a sink.
|
|
98
|
+
*/
|
|
99
|
+
export declare function crawlOptionsFor(settings: HostSettings, allowedHosts: readonly string[]): CrawlOptions;
|
|
100
|
+
//# sourceMappingURL=host-options.config.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HttpRequest, HttpResponseInit } from '@azure/functions';
|
|
2
|
+
/**
|
|
3
|
+
* @param status - The HTTP status.
|
|
4
|
+
* @param body - A JSON body.
|
|
5
|
+
* @returns The response.
|
|
6
|
+
*/
|
|
7
|
+
export declare function reply(status: number, body: unknown): HttpResponseInit;
|
|
8
|
+
/**
|
|
9
|
+
* An error the caller can act on: what went wrong, and the issues a recipe
|
|
10
|
+
* error lists (each with its JSON path).
|
|
11
|
+
*
|
|
12
|
+
* @param status - The HTTP status.
|
|
13
|
+
* @param error - What went wrong.
|
|
14
|
+
* @returns The response.
|
|
15
|
+
*/
|
|
16
|
+
export declare function problem(status: number, error: unknown): HttpResponseInit;
|
|
17
|
+
/**
|
|
18
|
+
* The request body as JSON.
|
|
19
|
+
*
|
|
20
|
+
* @param request - The request.
|
|
21
|
+
* @returns The body, or `undefined` when it is not JSON.
|
|
22
|
+
*/
|
|
23
|
+
export declare function readJson(request: HttpRequest): Promise<unknown>;
|
|
24
|
+
//# sourceMappingURL=http-reply.mapper.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { registerOpenCraw, hostJsonWarnings } from './open-craw-host';
|
|
2
|
+
export type { OpenCrawHost } from './open-craw-host';
|
|
3
|
+
export type { OpenCrawHostOptions, PoolSettings, McpSettings, CalloutSettings, HostSettings } from './host-options';
|
|
4
|
+
export { memoryRecipes, blobRecipes, RecipeStoreError } from './recipe-store';
|
|
5
|
+
export type { RecipeStore, StoredRecipes, BlobRecipesOptions } from './recipe-store';
|
|
6
|
+
export { blobResults } from './result-store';
|
|
7
|
+
export type { ResultStore, BlobResultsOptions } from './result-store';
|
|
8
|
+
export type { CrawlJob, CrawlResult, CrawlProgress, CrawlRequest, RecipeTask, RecipeTaskResult } from './crawl-run';
|
|
9
|
+
export type { ItemJob, ItemOutcome, PoolState, ItemRequest } from './worker-pools';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|