@notionhq/apps 0.0.17 → 0.0.19
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/AGENTS.md +27 -0
- package/README.md +77 -35
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.js +12 -7
- package/dist/cli/emit-manifest.d.ts +1 -1
- package/dist/cli/emit-manifest.d.ts.map +1 -1
- package/dist/cli/emit-manifest.js +66 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/notion-as-code/custom-agent.d.ts +1 -0
- package/dist/notion-as-code/custom-agent.d.ts.map +1 -1
- package/dist/notion-as-code/custom-agent.js +1 -1
- package/dist/notion-as-code/database.d.ts +90 -48
- package/dist/notion-as-code/database.d.ts.map +1 -1
- package/dist/notion-as-code/database.js +135 -45
- package/dist/notion-as-code/database.test.d.ts +2 -0
- package/dist/notion-as-code/database.test.d.ts.map +1 -0
- package/dist/notion-as-code/index.d.ts +2 -2
- package/dist/notion-as-code/index.d.ts.map +1 -1
- package/dist/notion-as-code/intents.d.ts +34 -2
- package/dist/notion-as-code/intents.d.ts.map +1 -1
- package/dist/notion-as-code/page.d.ts +1 -0
- package/dist/notion-as-code/page.d.ts.map +1 -1
- package/dist/notion-as-code/page.js +1 -0
- package/dist/notion-as-code/schema.d.ts +8 -4
- package/dist/notion-as-code/schema.d.ts.map +1 -1
- package/dist/notion-as-code/views.d.ts +29 -10
- package/dist/notion-as-code/views.d.ts.map +1 -1
- package/dist/sync.d.ts +33 -15
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +12 -0
- package/dist/workflow-access-types.test.d.ts +2 -0
- package/dist/workflow-access-types.test.d.ts.map +1 -0
- package/dist/workflow-access.d.ts +68 -0
- package/dist/workflow-access.d.ts.map +1 -0
- package/dist/workflow-access.js +135 -0
- package/dist/workflow-state.d.ts +13 -0
- package/dist/workflow-state.d.ts.map +1 -0
- package/dist/workflow-state.js +107 -0
- package/dist/workflow.d.ts +65 -9
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +119 -5
- package/docs/BUILD.md +134 -4
- package/package.json +1 -1
- package/skills/notion-as-code/SKILL.md +89 -49
- package/skills/sync/SKILL.md +21 -18
- package/skills/workflow/SKILL.md +101 -17
- package/src/cli/build.test.ts +148 -64
- package/src/cli/build.ts +13 -8
- package/src/cli/emit-manifest.ts +107 -0
- package/src/index.ts +21 -1
- package/src/notion-as-code/custom-agent.ts +2 -1
- package/src/notion-as-code/database.test.ts +661 -0
- package/src/notion-as-code/database.ts +349 -127
- package/src/notion-as-code/index.ts +16 -1
- package/src/notion-as-code/intents.ts +39 -2
- package/src/notion-as-code/page.ts +2 -0
- package/src/notion-as-code/schema.ts +11 -3
- package/src/notion-as-code/views.ts +29 -10
- package/src/sync.test.ts +295 -0
- package/src/sync.ts +85 -21
- package/src/workflow-access-types.test.ts +69 -0
- package/src/workflow-access.ts +299 -0
- package/src/workflow-state.ts +152 -0
- package/src/workflow.test.ts +441 -1
- package/src/workflow.ts +230 -13
package/dist/sync.js
CHANGED
|
@@ -35,6 +35,18 @@ function createSyncDefinition(configuration) {
|
|
|
35
35
|
if (change.type === "delete") {
|
|
36
36
|
return { ...change, targetDatabaseKey: database.key };
|
|
37
37
|
}
|
|
38
|
+
let hasOwnEnumerableProperty = false;
|
|
39
|
+
for (const propertyName in change.properties) {
|
|
40
|
+
if (Object.hasOwn(change.properties, propertyName)) {
|
|
41
|
+
hasOwnEnumerableProperty = true;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!hasOwnEnumerableProperty) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"Sync upsert properties must include at least one property."
|
|
48
|
+
);
|
|
49
|
+
}
|
|
38
50
|
return {
|
|
39
51
|
...change,
|
|
40
52
|
properties: {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-access-types.test.d.ts","sourceRoot":"","sources":["../src/workflow-access-types.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { CustomAgentHandle } from "./notion-as-code/custom-agent.js";
|
|
2
|
+
import type { DataSourceHandle, DatabaseHandle, SingleSourceDatabaseHandle } from "./notion-as-code/database.js";
|
|
3
|
+
import type { PageHandle } from "./notion-as-code/page.js";
|
|
4
|
+
/** A Notion-as-Code resource that can provide a named workflow binding. */
|
|
5
|
+
export type WorkflowAccessResource = PageHandle | DatabaseHandle | SingleSourceDatabaseHandle | DataSourceHandle | CustomAgentHandle;
|
|
6
|
+
/** Resource kinds accepted by workflow access declarations. */
|
|
7
|
+
export type WorkflowAccessResourceType = WorkflowAccessResource["resourceType"];
|
|
8
|
+
/** Levels accepted by pages, databases, and data sources. */
|
|
9
|
+
export type WorkflowAccessResourceLevel = "view" | "comment" | "edit" | "fullAccess";
|
|
10
|
+
/** The only level accepted by a custom agent. */
|
|
11
|
+
export type WorkflowAccessAgentLevel = "call";
|
|
12
|
+
/** Every level accepted by at least one workflow access resource. */
|
|
13
|
+
export type WorkflowAccessLevel = WorkflowAccessResourceLevel | WorkflowAccessAgentLevel;
|
|
14
|
+
/** The level set accepted by a particular resource kind. */
|
|
15
|
+
export type WorkflowAccessLevelFor<TType extends WorkflowAccessResourceType> = TType extends "customAgent" ? WorkflowAccessAgentLevel : WorkflowAccessResourceLevel;
|
|
16
|
+
type AccessResourceFor<TType extends WorkflowAccessResourceType> = Extract<WorkflowAccessResource, {
|
|
17
|
+
resourceType: TType;
|
|
18
|
+
}>;
|
|
19
|
+
/** A named binding declaration pairing one NaC handle with its allowed level. */
|
|
20
|
+
export type WorkflowAccessDeclaration = {
|
|
21
|
+
[TType in WorkflowAccessResourceType]: {
|
|
22
|
+
readonly resource: AccessResourceFor<TType>;
|
|
23
|
+
readonly level: WorkflowAccessLevelFor<TType>;
|
|
24
|
+
};
|
|
25
|
+
}[WorkflowAccessResourceType];
|
|
26
|
+
/** Named binding declarations keyed by the names exposed on workflow context. */
|
|
27
|
+
export type WorkflowAccessDeclarations = Readonly<Record<string, WorkflowAccessDeclaration>>;
|
|
28
|
+
/** A normalized named-binding requirement, including the required NaC resourceId. */
|
|
29
|
+
export type WorkflowAccessRequirement = {
|
|
30
|
+
[TType in WorkflowAccessResourceType]: {
|
|
31
|
+
readonly type: TType;
|
|
32
|
+
readonly resourceId: string;
|
|
33
|
+
readonly level: WorkflowAccessLevelFor<TType>;
|
|
34
|
+
};
|
|
35
|
+
}[WorkflowAccessResourceType];
|
|
36
|
+
/** Normalized named-binding requirements keyed by public alias. */
|
|
37
|
+
export type WorkflowAccessRequirements = Readonly<Record<string, WorkflowAccessRequirement>>;
|
|
38
|
+
/** The resolved NaC binding exposed to a workflow handler. */
|
|
39
|
+
export type WorkflowAccessValue<TType extends WorkflowAccessResourceType = WorkflowAccessResourceType> = Readonly<{
|
|
40
|
+
type: TType;
|
|
41
|
+
id: string;
|
|
42
|
+
}>;
|
|
43
|
+
/** Resolved access values keyed by their public aliases. */
|
|
44
|
+
export type WorkflowAccess<TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations> = Readonly<{
|
|
45
|
+
[TKey in keyof TAccess]: TAccess[TKey] extends {
|
|
46
|
+
readonly resource: {
|
|
47
|
+
readonly resourceType: infer TType;
|
|
48
|
+
};
|
|
49
|
+
} ? TType extends WorkflowAccessResourceType ? WorkflowAccessValue<TType> : never : never;
|
|
50
|
+
}>;
|
|
51
|
+
/** Resolved NaC bindings keyed by public aliases, without declaration metadata. */
|
|
52
|
+
export type WorkflowAccessBindings = Readonly<Record<string, WorkflowAccessValue>>;
|
|
53
|
+
/**
|
|
54
|
+
* Normalize public binding declarations without retaining the handle objects.
|
|
55
|
+
* Handles contain methods and schema objects, so they must never be cloned into
|
|
56
|
+
* the manifest or captured by the runtime transport. These declarations do not
|
|
57
|
+
* grant or change the workflow's existing Notion-module permissions.
|
|
58
|
+
*/
|
|
59
|
+
export declare function normalizeWorkflowAccess(declarations: WorkflowAccessDeclarations | undefined): WorkflowAccessRequirements;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve trusted per-invocation NaC bindings into the minimal context value.
|
|
62
|
+
* This exposes only declared aliases and does not determine Notion API
|
|
63
|
+
* authorization; the workflow's existing Notion-module permissions do that.
|
|
64
|
+
* The environment is deliberately not parsed when no binding is required.
|
|
65
|
+
*/
|
|
66
|
+
export declare function hydrateWorkflowAccess<TAccess extends WorkflowAccessDeclarations>(requirements: WorkflowAccessRequirements | undefined): WorkflowAccess<TAccess>;
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=workflow-access.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-access.d.ts","sourceRoot":"","sources":["../src/workflow-access.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const ACCESS_ALIAS_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/;
|
|
2
|
+
const RESERVED_ACCESS_ALIASES = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
3
|
+
const RESOURCE_TYPES = {
|
|
4
|
+
page: true,
|
|
5
|
+
database: true,
|
|
6
|
+
dataSource: true,
|
|
7
|
+
customAgent: true
|
|
8
|
+
};
|
|
9
|
+
function normalizeWorkflowAccess(declarations) {
|
|
10
|
+
const source = declarations ?? {};
|
|
11
|
+
assertPlainObject(source, "Workflow access must be an object keyed by alias.");
|
|
12
|
+
const keys = Object.keys(source);
|
|
13
|
+
if (Reflect.ownKeys(source).length !== keys.length) {
|
|
14
|
+
throw new Error("Workflow access aliases must be enumerable strings.");
|
|
15
|
+
}
|
|
16
|
+
if (keys.length > 100) {
|
|
17
|
+
throw new Error("Workflows support at most 100 access requirements.");
|
|
18
|
+
}
|
|
19
|
+
const normalized = /* @__PURE__ */ Object.create(null);
|
|
20
|
+
for (const alias of keys) {
|
|
21
|
+
if (!ACCESS_ALIAS_PATTERN.test(alias) || RESERVED_ACCESS_ALIASES.has(alias)) {
|
|
22
|
+
throw new Error(`Invalid workflow access alias: ${alias}`);
|
|
23
|
+
}
|
|
24
|
+
const declaration = source[alias];
|
|
25
|
+
if (!isRecord(declaration) || !Object.hasOwn(declaration, "resource") || !Object.hasOwn(declaration, "level")) {
|
|
26
|
+
throw new Error(`Workflow access "${alias}" must declare a resource and level.`);
|
|
27
|
+
}
|
|
28
|
+
const resource = declaration.resource;
|
|
29
|
+
if (!isRecord(resource) || !Object.hasOwn(resource, "resourceType") || !Object.hasOwn(resource, "resourceId") || typeof resource.resourceId !== "string" || resource.resourceId.length === 0 || !isWorkflowAccessResourceType(resource.resourceType)) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Workflow access "${alias}" must reference a supported NaC resource handle.`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
let requirement;
|
|
35
|
+
if (resource.resourceType === "customAgent") {
|
|
36
|
+
if (declaration.level !== "call") {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Workflow access "${alias}" custom agents only support level "call".`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
requirement = {
|
|
42
|
+
type: resource.resourceType,
|
|
43
|
+
resourceId: resource.resourceId,
|
|
44
|
+
level: declaration.level
|
|
45
|
+
};
|
|
46
|
+
} else {
|
|
47
|
+
if (!isWorkflowAccessResourceLevel(declaration.level)) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`Workflow access "${alias}" ${resource.resourceType} level must be view, comment, edit, or fullAccess.`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
requirement = {
|
|
53
|
+
type: resource.resourceType,
|
|
54
|
+
resourceId: resource.resourceId,
|
|
55
|
+
level: declaration.level
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
normalized[alias] = Object.freeze(requirement);
|
|
59
|
+
}
|
|
60
|
+
return Object.freeze(normalized);
|
|
61
|
+
}
|
|
62
|
+
function hydrateWorkflowAccess(requirements) {
|
|
63
|
+
const expected = requirements ?? {};
|
|
64
|
+
const aliases = Object.keys(expected);
|
|
65
|
+
const empty = /* @__PURE__ */ Object.create(null);
|
|
66
|
+
if (aliases.length === 0) {
|
|
67
|
+
return Object.freeze(empty);
|
|
68
|
+
}
|
|
69
|
+
const rawBindings = process.env.NOTION_ACCESS_BINDINGS;
|
|
70
|
+
if (rawBindings === void 0) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
"Workflow access requirements are not bound. Deploy and configure this requirement before running it."
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (rawBindings.length === 0) {
|
|
76
|
+
throw new Error("Invalid NOTION_ACCESS_BINDINGS metadata.");
|
|
77
|
+
}
|
|
78
|
+
let parsed;
|
|
79
|
+
try {
|
|
80
|
+
parsed = JSON.parse(rawBindings);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
throw new Error("Invalid NOTION_ACCESS_BINDINGS metadata.", { cause: error });
|
|
83
|
+
}
|
|
84
|
+
assertPlainObject(parsed, "Invalid NOTION_ACCESS_BINDINGS metadata.");
|
|
85
|
+
const bindingKeys = Object.keys(parsed);
|
|
86
|
+
if (Reflect.ownKeys(parsed).length !== bindingKeys.length || bindingKeys.length !== aliases.length || bindingKeys.some((alias) => !Object.hasOwn(expected, alias))) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
"Invalid NOTION_ACCESS_BINDINGS metadata: aliases do not match workflow access."
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const resolved = /* @__PURE__ */ Object.create(null);
|
|
92
|
+
for (const alias of aliases) {
|
|
93
|
+
const requirement = expected[alias];
|
|
94
|
+
if (!requirement) {
|
|
95
|
+
throw new Error(`Workflow access "${alias}" is not declared.`);
|
|
96
|
+
}
|
|
97
|
+
const binding = parsed[alias];
|
|
98
|
+
if (!isBinding(binding)) {
|
|
99
|
+
throw new Error(`Invalid NOTION_ACCESS_BINDINGS metadata for access "${alias}".`);
|
|
100
|
+
}
|
|
101
|
+
if (binding.type !== requirement.type || binding.resourceId !== requirement.resourceId || binding.level !== requirement.level) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`Workflow access "${alias}" binding does not match its declared type, resourceId, or level.`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
resolved[alias] = Object.freeze({ type: binding.type, id: binding.id });
|
|
107
|
+
}
|
|
108
|
+
return Object.freeze(resolved);
|
|
109
|
+
}
|
|
110
|
+
function isWorkflowAccessResourceType(value) {
|
|
111
|
+
return typeof value === "string" && Object.hasOwn(RESOURCE_TYPES, value);
|
|
112
|
+
}
|
|
113
|
+
function isWorkflowAccessResourceLevel(value) {
|
|
114
|
+
return value === "view" || value === "comment" || value === "edit" || value === "fullAccess";
|
|
115
|
+
}
|
|
116
|
+
function isBinding(value) {
|
|
117
|
+
if (!isRecord(value) || Reflect.ownKeys(value).length !== 4) return false;
|
|
118
|
+
const keys = Object.keys(value);
|
|
119
|
+
if (keys.length !== 4 || !keys.includes("type") || !keys.includes("resourceId") || !keys.includes("level") || !keys.includes("id")) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return isWorkflowAccessResourceType(value.type) && typeof value.resourceId === "string" && value.resourceId.length > 0 && typeof value.level === "string" && (isWorkflowAccessResourceLevel(value.level) || value.level === "call") && typeof value.id === "string" && value.id.length > 0;
|
|
123
|
+
}
|
|
124
|
+
function assertPlainObject(value, message) {
|
|
125
|
+
if (!isRecord(value)) throw new Error(message);
|
|
126
|
+
const prototype = Object.getPrototypeOf(value);
|
|
127
|
+
if (prototype !== Object.prototype && prototype !== null) throw new Error(message);
|
|
128
|
+
}
|
|
129
|
+
function isRecord(value) {
|
|
130
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
131
|
+
}
|
|
132
|
+
export {
|
|
133
|
+
hydrateWorkflowAccess,
|
|
134
|
+
normalizeWorkflowAccess
|
|
135
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RunMetadata } from "./runtime-metadata.js";
|
|
2
|
+
export type WorkflowStateValue = null | boolean | number | string | ReadonlyArray<WorkflowStateValue> | {
|
|
3
|
+
readonly [key: string]: WorkflowStateValue;
|
|
4
|
+
};
|
|
5
|
+
export type WorkflowState = {
|
|
6
|
+
get(key: string): Promise<WorkflowStateValue | undefined>;
|
|
7
|
+
set(key: string, value: WorkflowStateValue | undefined): void;
|
|
8
|
+
};
|
|
9
|
+
export declare function createWorkflowStepState(metadata: Pick<RunMetadata, "workerId">, stepId: string): {
|
|
10
|
+
state: WorkflowState;
|
|
11
|
+
run<T>(fn: () => T | Promise<T>): Promise<T>;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=workflow-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-state.d.ts","sourceRoot":"","sources":["../src/workflow-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,MAAM,kBAAkB,GAC3B,IAAI,GACJ,OAAO,GACP,MAAM,GACN,MAAM,GACN,aAAa,CAAC,kBAAkB,CAAC,GACjC;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;IAC1D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,SAAS,GAAG,IAAI,CAAC;CAC9D,CAAC;AAeF,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EACvC,MAAM,EAAE,MAAM,GACZ;IACF,KAAK,EAAE,aAAa,CAAC;IACrB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7C,CA2DA"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const MAX_STATE_KEY_BYTES = 256;
|
|
2
|
+
const WORKFLOW_CAPABILITY_KEY_ENV = "NOTION_WORKFLOW_CAPABILITY_KEY";
|
|
3
|
+
function createWorkflowStepState(metadata, stepId) {
|
|
4
|
+
const scope = {
|
|
5
|
+
id: stepId,
|
|
6
|
+
active: true,
|
|
7
|
+
mutations: /* @__PURE__ */ new Map()
|
|
8
|
+
};
|
|
9
|
+
const state = {
|
|
10
|
+
async get(key) {
|
|
11
|
+
requireActiveStep(scope, "get");
|
|
12
|
+
validateStateKey(key);
|
|
13
|
+
const pending = scope.mutations.get(key);
|
|
14
|
+
if (pending?.operation === "set") {
|
|
15
|
+
return pending.value;
|
|
16
|
+
}
|
|
17
|
+
if (pending?.operation === "delete") {
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
20
|
+
const response = await requestWorkflowState(metadata, {
|
|
21
|
+
operation: "get",
|
|
22
|
+
key
|
|
23
|
+
});
|
|
24
|
+
const body = JSON.parse(
|
|
25
|
+
await response.text()
|
|
26
|
+
);
|
|
27
|
+
if (!body.exists) {
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
return body.value;
|
|
31
|
+
},
|
|
32
|
+
set(key, value) {
|
|
33
|
+
requireActiveStep(scope, "set");
|
|
34
|
+
validateStateKey(key);
|
|
35
|
+
if (value === void 0) {
|
|
36
|
+
recordMutation(scope, { operation: "delete", key });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
recordMutation(scope, { operation: "set", key, value });
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
state,
|
|
44
|
+
async run(fn) {
|
|
45
|
+
try {
|
|
46
|
+
const result = await fn();
|
|
47
|
+
if (scope.mutations.size > 0) {
|
|
48
|
+
await requestWorkflowState(metadata, {
|
|
49
|
+
operation: "commit",
|
|
50
|
+
operationId: scope.id,
|
|
51
|
+
mutations: [...scope.mutations.values()]
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
} finally {
|
|
56
|
+
scope.active = false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function requireActiveStep(expectedScope, operation) {
|
|
62
|
+
if (!expectedScope.active) {
|
|
63
|
+
throw new Error(`state.${operation}() must be called inside context.step().`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function recordMutation(scope, mutation) {
|
|
67
|
+
scope.mutations.set(mutation.key, mutation);
|
|
68
|
+
}
|
|
69
|
+
async function requestWorkflowState(metadata, request) {
|
|
70
|
+
const baseUrl = process.env.NOTION_API_BASE_URL;
|
|
71
|
+
const token = process.env.NOTION_API_TOKEN;
|
|
72
|
+
const capabilityKey = process.env[WORKFLOW_CAPABILITY_KEY_ENV];
|
|
73
|
+
if (!baseUrl || !token || !capabilityKey) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Workflow state is only available when the workflow runtime provides NOTION_API_BASE_URL, NOTION_API_TOKEN, and ${WORKFLOW_CAPABILITY_KEY_ENV}.`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
const response = await fetch(`${baseUrl.replace(/\/$/, "")}/api/v3/workersWorkflowState`, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: {
|
|
81
|
+
authorization: `Bearer ${token}`,
|
|
82
|
+
"content-type": "application/json"
|
|
83
|
+
},
|
|
84
|
+
body: JSON.stringify({
|
|
85
|
+
...request,
|
|
86
|
+
workerId: metadata.workerId,
|
|
87
|
+
capabilityKey
|
|
88
|
+
})
|
|
89
|
+
});
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Workflow state ${request.operation} failed with status ${response.status}.`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return response;
|
|
96
|
+
}
|
|
97
|
+
function validateStateKey(key) {
|
|
98
|
+
if (key.length === 0) {
|
|
99
|
+
throw new Error("Workflow state keys must not be empty.");
|
|
100
|
+
}
|
|
101
|
+
if (Buffer.byteLength(key) > MAX_STATE_KEY_BYTES) {
|
|
102
|
+
throw new Error(`Workflow state keys must be at most ${MAX_STATE_KEY_BYTES} UTF-8 bytes.`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export {
|
|
106
|
+
createWorkflowStepState
|
|
107
|
+
};
|
package/dist/workflow.d.ts
CHANGED
|
@@ -1,11 +1,44 @@
|
|
|
1
1
|
import { type WorkflowConnectionDeclarations, type WorkflowConnectionRequirement, type WorkflowConnections } from "./connections.js";
|
|
2
|
+
import { type WorkflowAccess, type WorkflowAccessDeclarations, type WorkflowAccessRequirements } from "./workflow-access.js";
|
|
2
3
|
import type { CapabilityContext } from "./context.js";
|
|
3
4
|
import { type RunMetadata } from "./runtime-metadata.js";
|
|
5
|
+
import { type WorkflowState } from "./workflow-state.js";
|
|
4
6
|
import type { WorkflowEventMap, WorkflowTrigger, WorkflowTriggerCreators, WorkflowTriggerForConnections } from "./triggers.generated.js";
|
|
5
7
|
type HandlerOptions = {
|
|
6
8
|
/** Return the concrete result instead of writing the output envelope. */
|
|
7
9
|
concreteOutput?: true;
|
|
8
10
|
};
|
|
11
|
+
type WorkflowWaitDurationValues = {
|
|
12
|
+
milliseconds?: number;
|
|
13
|
+
seconds?: number;
|
|
14
|
+
minutes?: number;
|
|
15
|
+
hours?: number;
|
|
16
|
+
days?: number;
|
|
17
|
+
weeks?: number;
|
|
18
|
+
};
|
|
19
|
+
export type WorkflowWaitDuration = {
|
|
20
|
+
[Unit in keyof WorkflowWaitDurationValues]-?: Required<Pick<WorkflowWaitDurationValues, Unit>> & WorkflowWaitDurationValues;
|
|
21
|
+
}[keyof WorkflowWaitDurationValues];
|
|
22
|
+
type WorkflowWaitKey = string | string[];
|
|
23
|
+
export type WorkflowWaitUntilOptions = {
|
|
24
|
+
at: Date;
|
|
25
|
+
key?: WorkflowWaitKey;
|
|
26
|
+
} | {
|
|
27
|
+
after: WorkflowWaitDuration;
|
|
28
|
+
key?: WorkflowWaitKey;
|
|
29
|
+
};
|
|
30
|
+
export type WorkflowWaitUntilResult = {
|
|
31
|
+
status: "waiting";
|
|
32
|
+
wait: {
|
|
33
|
+
type: "until";
|
|
34
|
+
name: string;
|
|
35
|
+
resumeAtMs: number;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
type WorkflowHandlerResult = {
|
|
39
|
+
status: "success";
|
|
40
|
+
} | WorkflowWaitUntilResult;
|
|
41
|
+
export type { WorkflowAccess, WorkflowAccessAgentLevel, WorkflowAccessBindings, WorkflowAccessDeclaration, WorkflowAccessDeclarations, WorkflowAccessLevel, WorkflowAccessLevelFor, WorkflowAccessResource, WorkflowAccessResourceLevel, WorkflowAccessResourceType, WorkflowAccessRequirement, WorkflowAccessRequirements, WorkflowAccessValue, } from "./workflow-access.js";
|
|
9
42
|
export type WorkflowEvent = WorkflowEventMap[keyof WorkflowEventMap];
|
|
10
43
|
export type WorkflowEventForTrigger<T extends WorkflowTrigger> = WorkflowEventMap[T["type"]];
|
|
11
44
|
export type WorkflowEventForTriggers<T extends readonly WorkflowTrigger[]> = WorkflowEventForTrigger<T[number]>;
|
|
@@ -13,7 +46,7 @@ export { connections, type WorkflowConnection, type WorkflowConnectionDeclaratio
|
|
|
13
46
|
/**
|
|
14
47
|
* Configuration passed to {@link workflow}.
|
|
15
48
|
*/
|
|
16
|
-
export type WorkflowConfiguration<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], TConnections extends WorkflowConnectionDeclarations = WorkflowConnectionDeclarations> = {
|
|
49
|
+
export type WorkflowConfiguration<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], TConnections extends WorkflowConnectionDeclarations = WorkflowConnectionDeclarations, TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations> = {
|
|
17
50
|
/**
|
|
18
51
|
* A human-readable name for the workflow, shown in the UI when viewing workflows
|
|
19
52
|
*/
|
|
@@ -28,14 +61,20 @@ export type WorkflowConfiguration<TTriggers extends readonly [WorkflowTrigger, .
|
|
|
28
61
|
* Each trigger defines a specific event or condition that causes the workflow to run.
|
|
29
62
|
*/
|
|
30
63
|
triggers: TTriggers;
|
|
64
|
+
/**
|
|
65
|
+
* Notion-as-Code resources whose access is configured during cloud deployment.
|
|
66
|
+
* Deployment reconciles grants through the existing Notion-module permissions
|
|
67
|
+
* and supplies named runtime bindings on `context.access`.
|
|
68
|
+
*/
|
|
69
|
+
access?: TAccess;
|
|
31
70
|
/**
|
|
32
71
|
* Connections that must be set up before this workflow can run.
|
|
33
72
|
*/
|
|
34
73
|
connections?: TConnections;
|
|
35
|
-
handler: (event: WorkflowEventForTriggers<TTriggers>, context: WorkflowContext<TConnections>) => Promise<void> | void;
|
|
74
|
+
handler: (event: WorkflowEventForTriggers<TTriggers>, context: WorkflowContext<TConnections, TAccess>) => Promise<void> | void;
|
|
36
75
|
};
|
|
37
76
|
/** Configuration that checks trigger keys against declared connections. */
|
|
38
|
-
export type WorkflowTriggerConfiguration<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], TConnections extends WorkflowConnectionDeclarations> = Omit<WorkflowConfiguration<TTriggers, TConnections>, "triggers"> & {
|
|
77
|
+
export type WorkflowTriggerConfiguration<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], TConnections extends WorkflowConnectionDeclarations, TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations> = Omit<WorkflowConfiguration<TTriggers, TConnections, TAccess>, "triggers"> & {
|
|
39
78
|
triggers: (context: {
|
|
40
79
|
triggers: WorkflowTriggerCreators<NoInfer<TConnections>>;
|
|
41
80
|
}) => TTriggers;
|
|
@@ -56,10 +95,9 @@ export type Workflow<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTri
|
|
|
56
95
|
description: string;
|
|
57
96
|
triggers: TTriggers;
|
|
58
97
|
connections?: readonly WorkflowConnectionRequirement[];
|
|
98
|
+
access?: WorkflowAccessRequirements;
|
|
59
99
|
};
|
|
60
|
-
handler: (event: WorkflowEventForTriggers<TTriggers>, options?: HandlerOptions) => Promise<
|
|
61
|
-
status: "success";
|
|
62
|
-
} | undefined>;
|
|
100
|
+
handler: (event: WorkflowEventForTriggers<TTriggers>, options?: HandlerOptions) => Promise<WorkflowHandlerResult | undefined>;
|
|
63
101
|
};
|
|
64
102
|
/**
|
|
65
103
|
* Create a workflow capability.
|
|
@@ -90,8 +128,8 @@ export type Workflow<TTriggers extends readonly [WorkflowTrigger, ...WorkflowTri
|
|
|
90
128
|
export declare function workflow<const TTriggers extends readonly [
|
|
91
129
|
WorkflowTriggerForConnections<NoInfer<TConnections>>,
|
|
92
130
|
...WorkflowTriggerForConnections<NoInfer<TConnections>>[]
|
|
93
|
-
], const TConnections extends WorkflowConnectionDeclarations = Record<never, never>>(configuration: WorkflowTriggerConfiguration<TTriggers, TConnections>): Workflow<TTriggers>;
|
|
94
|
-
export declare function workflow<const TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], const TConnections extends WorkflowConnectionDeclarations = Record<never, never>>(configuration: WorkflowConfiguration<TTriggers, TConnections>): Workflow<TTriggers>;
|
|
131
|
+
], const TConnections extends WorkflowConnectionDeclarations = Record<never, never>, const TAccess extends WorkflowAccessDeclarations = Record<never, never>>(configuration: WorkflowTriggerConfiguration<TTriggers, TConnections, TAccess>): Workflow<TTriggers>;
|
|
132
|
+
export declare function workflow<const TTriggers extends readonly [WorkflowTrigger, ...WorkflowTrigger[]], const TConnections extends WorkflowConnectionDeclarations = Record<never, never>, const TAccess extends WorkflowAccessDeclarations = Record<never, never>>(configuration: WorkflowConfiguration<TTriggers, TConnections, TAccess>): Workflow<TTriggers>;
|
|
95
133
|
/** Context passed to a workflow step. */
|
|
96
134
|
export type StepContext = {
|
|
97
135
|
/**
|
|
@@ -99,6 +137,13 @@ export type StepContext = {
|
|
|
99
137
|
* Use this to make side effects idempotent when the workflow is retried.
|
|
100
138
|
*/
|
|
101
139
|
id: string;
|
|
140
|
+
/**
|
|
141
|
+
* Durable key-value state shared by every run of this workflow.
|
|
142
|
+
*
|
|
143
|
+
* State is exposed on the step context because every operation participates
|
|
144
|
+
* in the active step's durability and replay boundary.
|
|
145
|
+
*/
|
|
146
|
+
state: WorkflowState;
|
|
102
147
|
};
|
|
103
148
|
type WorkflowStepResult<T> = T extends void ? null : T;
|
|
104
149
|
/** Options for a workflow step. */
|
|
@@ -114,8 +159,17 @@ type WorkflowStep = {
|
|
|
114
159
|
<T>(name: string, fn: (context: StepContext) => T | Promise<T>): Promise<WorkflowStepResult<T>>;
|
|
115
160
|
<T>(name: string, options: WorkflowStepOptions, fn: (context: StepContext) => T | Promise<T>): Promise<WorkflowStepResult<T>>;
|
|
116
161
|
};
|
|
162
|
+
type WorkflowWait = {
|
|
163
|
+
/**
|
|
164
|
+
* Suspend the workflow until a relative duration has elapsed or an absolute
|
|
165
|
+
* date has been reached.
|
|
166
|
+
*/
|
|
167
|
+
until(name: string, options: WorkflowWaitUntilOptions): Promise<void>;
|
|
168
|
+
};
|
|
117
169
|
/** Context passed to a workflow handler. */
|
|
118
|
-
export type WorkflowContext<TConnections extends WorkflowConnectionDeclarations = WorkflowConnectionDeclarations> = CapabilityContext & {
|
|
170
|
+
export type WorkflowContext<TConnections extends WorkflowConnectionDeclarations = WorkflowConnectionDeclarations, TAccess extends WorkflowAccessDeclarations = WorkflowAccessDeclarations> = CapabilityContext & {
|
|
171
|
+
/** Resolved NaC bindings for this invocation; UI-granted resources are not added here. */
|
|
172
|
+
readonly access: WorkflowAccess<TAccess>;
|
|
119
173
|
connections: WorkflowConnections<TConnections>;
|
|
120
174
|
} & RunMetadata & {
|
|
121
175
|
/**
|
|
@@ -139,5 +193,7 @@ export type WorkflowContext<TConnections extends WorkflowConnectionDeclarations
|
|
|
139
193
|
* ```
|
|
140
194
|
*/
|
|
141
195
|
step: WorkflowStep;
|
|
196
|
+
/** Suspend this workflow without consuming compute resources. */
|
|
197
|
+
wait: WorkflowWait;
|
|
142
198
|
};
|
|
143
199
|
//# sourceMappingURL=workflow.d.ts.map
|
package/dist/workflow.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,8BAA8B,EACnC,KAAK,6BAA6B,EAClC,KAAK,mBAAmB,EACxB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
|