@hatchingpoint/point 0.0.6 → 0.0.8

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.
@@ -1,222 +1,222 @@
1
- import type {
2
- PointSemanticBinding,
3
- PointSemanticCalculationStatement,
4
- PointSemanticCommandStatement,
5
- PointSemanticDeclaration,
6
- PointSemanticExpression,
7
- PointSemanticLabelStatement,
8
- PointSemanticMutationStatement,
9
- PointSemanticOutputBinding,
10
- PointSemanticPolicyStatement,
11
- PointSemanticProgram,
12
- PointSemanticRouteStatement,
13
- PointSemanticRuleStatement,
14
- PointSemanticTypeExpression,
15
- PointSemanticViewStatement,
16
- PointSemanticWorkflowStatement,
17
- PointSemanticActionStatement,
18
- } from "./ast.ts";
19
-
20
- export function formatSemanticProgram(program: PointSemanticProgram): string {
21
- const blocks: string[] = [];
22
- if (program.module) blocks.push(`module ${program.module}`);
23
- for (const use of program.uses) {
24
- blocks.push(use.from ? `use ${use.moduleName} from ${JSON.stringify(use.from)}` : `use ${use.moduleName}`);
25
- }
26
- for (const declaration of program.declarations) {
27
- blocks.push(formatDeclaration(declaration).join("\n"));
28
- }
29
- return `${blocks.join("\n\n")}\n`;
30
- }
31
-
32
- function formatDeclaration(declaration: PointSemanticDeclaration): string[] {
33
- switch (declaration.kind) {
34
- case "record":
35
- return [`record ${declaration.name}`, ...declaration.fields.map((field) => ` ${field.label}: ${formatType(field.type)}`)];
36
- case "external":
37
- return [
38
- `external ${declaration.name}`,
39
- ...declaration.functions.map(
40
- (fn) =>
41
- ` ${fn.label}(${fn.params.map(formatBinding).join(", ")}): ${formatType(fn.returnType)} from ${JSON.stringify(fn.from)}${fn.importAs ? ` as ${fn.importAs}` : ""}`,
42
- ),
43
- ];
44
- case "calculation":
45
- return [
46
- `calculation ${declaration.name}`,
47
- ...formatInputs(declaration.inputs),
48
- ...formatOutput(declaration.output, declaration.kind),
49
- ...declaration.body.map((statement) => ` ${formatCalculationStatement(statement)}`),
50
- ];
51
- case "rule":
52
- return [
53
- `rule ${declaration.name}`,
54
- ...formatInputs(declaration.inputs),
55
- ...formatOutput(declaration.output, declaration.kind),
56
- ...declaration.body.flatMap((statement) => formatRuleStatement(statement)),
57
- ];
58
- case "label":
59
- return [
60
- `label ${declaration.name}`,
61
- ...formatInputs(declaration.inputs),
62
- ...formatOutput(declaration.output, declaration.kind),
63
- ...declaration.body.map((statement) => ` ${formatLabelStatement(statement)}`),
64
- ];
65
- case "action":
66
- return [
67
- `action ${declaration.name}`,
68
- ...formatInputs(declaration.inputs),
69
- ...formatOutput(declaration.output, declaration.kind),
70
- ...(declaration.touches.length > 0 ? [` touches ${declaration.touches.join(", ")}`] : []),
71
- ...declaration.body.map((statement) => ` ${formatActionStatement(statement)}`),
72
- ];
73
- case "policy":
74
- return [
75
- `policy ${declaration.name}`,
76
- ...formatInputs(declaration.inputs),
77
- ...declaration.body.map((statement) => ` ${formatPolicyStatement(statement)}`),
78
- ];
79
- case "view":
80
- return [
81
- `view ${declaration.name}`,
82
- ...formatInputs(declaration.inputs),
83
- ...formatViewOutput(declaration.output),
84
- ...declaration.body.map((statement) => ` ${formatViewStatement(statement)}`),
85
- ];
86
- case "route":
87
- return [
88
- `route ${declaration.name}`,
89
- ` method ${declaration.method}`,
90
- ` path ${JSON.stringify(declaration.path)}`,
91
- ...formatInputs(declaration.inputs).map((line) => ` ${line.trimStart()}`),
92
- ...formatOutput(declaration.output, declaration.kind).map((line) => ` ${line.trimStart()}`),
93
- ...declaration.body.map((statement) => ` ${formatRouteStatement(statement)}`),
94
- ];
95
- case "workflow":
96
- return [
97
- `workflow ${declaration.name}`,
98
- ...formatInputs(declaration.inputs),
99
- ...formatOutput(declaration.output, declaration.kind),
100
- ...declaration.body.map((statement) => ` ${formatWorkflowStatement(statement)}`),
101
- ];
102
- case "command":
103
- return [
104
- `command ${declaration.name}`,
105
- ...formatInputs(declaration.inputs),
106
- ...formatOutput(declaration.output, declaration.kind),
107
- ...declaration.body.map((statement) => ` ${formatCommandStatement(statement)}`),
108
- ];
109
- }
110
- }
111
-
112
- function formatInputs(inputs: PointSemanticBinding[]): string[] {
113
- return inputs.map((input) => ` input ${formatBinding(input)}`);
114
- }
115
-
116
- function formatBinding(binding: PointSemanticBinding): string {
117
- return `${binding.label}: ${formatType(binding.type)}`;
118
- }
119
-
120
- function formatOutput(output: PointSemanticOutputBinding, kind: PointSemanticDeclaration["kind"]): string[] {
121
- if (kind === "label" && output.name === "result") return [` output ${formatType(output.type)}`];
122
- if (kind === "policy") return [];
123
- if (kind === "view" && output.name === "page" && output.type.name === "Page") return [];
124
- if (output.type.name === "Void" && output.name === "result") {
125
- if (kind === "action" || kind === "command") return [" output Void"];
126
- if (kind === "calculation" || kind === "rule" || kind === "workflow") return [];
127
- }
128
- return [` output ${output.name}: ${formatType(output.type)}`];
129
- }
130
-
131
- function formatViewOutput(output: PointSemanticOutputBinding): string[] {
132
- if (output.name === "page" && output.type.name === "Page") return [];
133
- return formatOutput(output, "view");
134
- }
135
-
136
- function formatCalculationStatement(statement: PointSemanticCalculationStatement): string {
137
- if (statement.kind === "assignIs") return `${statement.name} is ${formatExpression(statement.value)}`;
138
- if (statement.kind === "startsAt") return `${statement.name} starts at ${formatExpression(statement.value)}`;
139
- if (statement.kind === "startsAs") return `${statement.name} starts as ${formatExpression(statement.value)}`;
140
- if (statement.kind === "forEach") {
141
- return [`for each ${statement.item} in ${formatExpression(statement.iterable)}`, ...statement.body.map((mutation) => ` ${formatMutation(mutation)}`)].join(
142
- "\n",
143
- );
144
- }
145
- if (statement.kind === "return") return `return ${formatExpression(statement.value)}`;
146
- return formatMutation(statement);
147
- }
148
-
149
- function formatRuleStatement(statement: PointSemanticRuleStatement): string[] {
150
- if (statement.kind === "startsAt") return [` ${statement.name} starts at ${formatExpression(statement.value)}`];
151
- if (statement.kind === "addWhen") return [` add ${formatExpression(statement.amount)} when ${formatExpression(statement.condition)}`];
152
- if (statement.kind === "forEach") {
153
- return [
154
- ` for each ${statement.item} in ${formatExpression(statement.iterable)}`,
155
- ...statement.body.map((mutation) => ` ${formatMutation(mutation)}`),
156
- ];
157
- }
158
- if (statement.kind === "return") return [` return ${formatExpression(statement.value)}`];
159
- return [` ${formatMutation(statement)}`];
160
- }
161
-
162
- function formatLabelStatement(statement: PointSemanticLabelStatement): string {
163
- if (statement.kind === "whenReturn") return `when ${formatExpression(statement.condition)} return ${formatExpression(statement.value)}`;
164
- return `otherwise return ${formatExpression(statement.value)}`;
165
- }
166
-
167
- function formatActionStatement(statement: PointSemanticActionStatement): string {
168
- return `return ${formatExpression(statement.value)}`;
169
- }
170
-
171
- function formatPolicyStatement(statement: PointSemanticPolicyStatement): string {
172
- if (statement.kind === "deny") return `deny ${formatExpression(statement.condition)}`;
173
- if (statement.kind === "require") return `require ${formatExpression(statement.condition)}`;
174
- return `allow ${formatExpression(statement.condition)}`;
175
- }
176
-
177
- function formatViewStatement(statement: PointSemanticViewStatement): string {
178
- if (statement.kind === "whenRender") return `when ${formatExpression(statement.condition)} render ${formatExpression(statement.value)}`;
179
- return `render ${formatExpression(statement.value)}`;
180
- }
181
-
182
- function formatRouteStatement(statement: PointSemanticRouteStatement): string {
183
- return `return ${formatExpression(statement.value)}`;
184
- }
185
-
186
- function formatWorkflowStatement(statement: PointSemanticWorkflowStatement): string {
187
- if (statement.kind === "step") return `step ${statement.name} is ${formatExpression(statement.value)}`;
188
- return `return ${formatExpression(statement.value)}`;
189
- }
190
-
191
- function formatCommandStatement(statement: PointSemanticCommandStatement): string {
192
- return `return ${formatExpression(statement.value)}`;
193
- }
194
-
195
- function formatMutation(statement: PointSemanticMutationStatement): string {
196
- if (statement.kind === "addTo") return `add ${formatExpression(statement.amount)} to ${statement.target}`;
197
- if (statement.kind === "subtractFrom") return `subtract ${formatExpression(statement.amount)} from ${statement.target}`;
198
- return `set ${statement.target} to ${formatExpression(statement.value)}`;
199
- }
200
-
201
- function formatExpression(expression: PointSemanticExpression): string {
202
- if (expression.kind === "literal") {
203
- if (expression.value === null) return "none";
204
- return JSON.stringify(expression.value);
205
- }
206
- if (expression.kind === "name") return expression.label;
207
- if (expression.kind === "property") return `${formatExpression(expression.target)}.${expression.label}`;
208
- if (expression.kind === "binary") return `${formatExpression(expression.left)} ${expression.operator} ${formatExpression(expression.right)}`;
209
- if (expression.kind === "call") return `${expression.callee}(${expression.args.map(formatExpression).join(", ")})`;
210
- if (expression.kind === "await") return `await ${formatExpression(expression.value)}`;
211
- if (expression.kind === "list") return `[${expression.items.map(formatExpression).join(", ")}]`;
212
- if (expression.kind === "record") {
213
- return `{ ${expression.fields.map((field) => `${field.label}: ${formatExpression(field.value)}`).join(", ")} }`;
214
- }
215
- return `Error ${JSON.stringify(expression.message)}`;
216
- }
217
-
218
- function formatType(type: PointSemanticTypeExpression): string {
219
- if (type.name === "Or") return type.args.map(formatType).join(" or ");
220
- if (type.args.length === 0) return type.name;
221
- return `${type.name}<${type.args.map(formatType).join(", ")}>`;
222
- }
1
+ import type {
2
+ PointSemanticBinding,
3
+ PointSemanticCalculationStatement,
4
+ PointSemanticCommandStatement,
5
+ PointSemanticDeclaration,
6
+ PointSemanticExpression,
7
+ PointSemanticLabelStatement,
8
+ PointSemanticMutationStatement,
9
+ PointSemanticOutputBinding,
10
+ PointSemanticPolicyStatement,
11
+ PointSemanticProgram,
12
+ PointSemanticRouteStatement,
13
+ PointSemanticRuleStatement,
14
+ PointSemanticTypeExpression,
15
+ PointSemanticViewStatement,
16
+ PointSemanticWorkflowStatement,
17
+ PointSemanticActionStatement,
18
+ } from "./ast.ts";
19
+
20
+ export function formatSemanticProgram(program: PointSemanticProgram): string {
21
+ const blocks: string[] = [];
22
+ if (program.module) blocks.push(`module ${program.module}`);
23
+ for (const use of program.uses) {
24
+ blocks.push(use.from ? `use ${use.moduleName} from ${JSON.stringify(use.from)}` : `use ${use.moduleName}`);
25
+ }
26
+ for (const declaration of program.declarations) {
27
+ blocks.push(formatDeclaration(declaration).join("\n"));
28
+ }
29
+ return `${blocks.join("\n\n")}\n`;
30
+ }
31
+
32
+ function formatDeclaration(declaration: PointSemanticDeclaration): string[] {
33
+ switch (declaration.kind) {
34
+ case "record":
35
+ return [`record ${declaration.name}`, ...declaration.fields.map((field) => ` ${field.label}: ${formatType(field.type)}`)];
36
+ case "external":
37
+ return [
38
+ `external ${declaration.name}`,
39
+ ...declaration.functions.map(
40
+ (fn) =>
41
+ ` ${fn.label}(${fn.params.map(formatBinding).join(", ")}): ${formatType(fn.returnType)} from ${JSON.stringify(fn.from)}${fn.importAs ? ` as ${fn.importAs}` : ""}`,
42
+ ),
43
+ ];
44
+ case "calculation":
45
+ return [
46
+ `calculation ${declaration.name}`,
47
+ ...formatInputs(declaration.inputs),
48
+ ...formatOutput(declaration.output, declaration.kind),
49
+ ...declaration.body.map((statement) => ` ${formatCalculationStatement(statement)}`),
50
+ ];
51
+ case "rule":
52
+ return [
53
+ `rule ${declaration.name}`,
54
+ ...formatInputs(declaration.inputs),
55
+ ...formatOutput(declaration.output, declaration.kind),
56
+ ...declaration.body.flatMap((statement) => formatRuleStatement(statement)),
57
+ ];
58
+ case "label":
59
+ return [
60
+ `label ${declaration.name}`,
61
+ ...formatInputs(declaration.inputs),
62
+ ...formatOutput(declaration.output, declaration.kind),
63
+ ...declaration.body.map((statement) => ` ${formatLabelStatement(statement)}`),
64
+ ];
65
+ case "action":
66
+ return [
67
+ `action ${declaration.name}`,
68
+ ...formatInputs(declaration.inputs),
69
+ ...formatOutput(declaration.output, declaration.kind),
70
+ ...(declaration.touches.length > 0 ? [` touches ${declaration.touches.join(", ")}`] : []),
71
+ ...declaration.body.map((statement) => ` ${formatActionStatement(statement)}`),
72
+ ];
73
+ case "policy":
74
+ return [
75
+ `policy ${declaration.name}`,
76
+ ...formatInputs(declaration.inputs),
77
+ ...declaration.body.map((statement) => ` ${formatPolicyStatement(statement)}`),
78
+ ];
79
+ case "view":
80
+ return [
81
+ `view ${declaration.name}`,
82
+ ...formatInputs(declaration.inputs),
83
+ ...formatViewOutput(declaration.output),
84
+ ...declaration.body.map((statement) => ` ${formatViewStatement(statement)}`),
85
+ ];
86
+ case "route":
87
+ return [
88
+ `route ${declaration.name}`,
89
+ ` method ${declaration.method}`,
90
+ ` path ${JSON.stringify(declaration.path)}`,
91
+ ...formatInputs(declaration.inputs).map((line) => ` ${line.trimStart()}`),
92
+ ...formatOutput(declaration.output, declaration.kind).map((line) => ` ${line.trimStart()}`),
93
+ ...declaration.body.map((statement) => ` ${formatRouteStatement(statement)}`),
94
+ ];
95
+ case "workflow":
96
+ return [
97
+ `workflow ${declaration.name}`,
98
+ ...formatInputs(declaration.inputs),
99
+ ...formatOutput(declaration.output, declaration.kind),
100
+ ...declaration.body.map((statement) => ` ${formatWorkflowStatement(statement)}`),
101
+ ];
102
+ case "command":
103
+ return [
104
+ `command ${declaration.name}`,
105
+ ...formatInputs(declaration.inputs),
106
+ ...formatOutput(declaration.output, declaration.kind),
107
+ ...declaration.body.map((statement) => ` ${formatCommandStatement(statement)}`),
108
+ ];
109
+ }
110
+ }
111
+
112
+ function formatInputs(inputs: PointSemanticBinding[]): string[] {
113
+ return inputs.map((input) => ` input ${formatBinding(input)}`);
114
+ }
115
+
116
+ function formatBinding(binding: PointSemanticBinding): string {
117
+ return `${binding.label}: ${formatType(binding.type)}`;
118
+ }
119
+
120
+ function formatOutput(output: PointSemanticOutputBinding, kind: PointSemanticDeclaration["kind"]): string[] {
121
+ if (kind === "label" && output.name === "result") return [` output ${formatType(output.type)}`];
122
+ if (kind === "policy") return [];
123
+ if (kind === "view" && output.name === "page" && output.type.name === "Page") return [];
124
+ if (output.type.name === "Void" && output.name === "result") {
125
+ if (kind === "action" || kind === "command") return [" output Void"];
126
+ if (kind === "calculation" || kind === "rule" || kind === "workflow") return [];
127
+ }
128
+ return [` output ${output.name}: ${formatType(output.type)}`];
129
+ }
130
+
131
+ function formatViewOutput(output: PointSemanticOutputBinding): string[] {
132
+ if (output.name === "page" && output.type.name === "Page") return [];
133
+ return formatOutput(output, "view");
134
+ }
135
+
136
+ function formatCalculationStatement(statement: PointSemanticCalculationStatement): string {
137
+ if (statement.kind === "assignIs") return `${statement.name} is ${formatExpression(statement.value)}`;
138
+ if (statement.kind === "startsAt") return `${statement.name} starts at ${formatExpression(statement.value)}`;
139
+ if (statement.kind === "startsAs") return `${statement.name} starts as ${formatExpression(statement.value)}`;
140
+ if (statement.kind === "forEach") {
141
+ return [`for each ${statement.item} in ${formatExpression(statement.iterable)}`, ...statement.body.map((mutation) => ` ${formatMutation(mutation)}`)].join(
142
+ "\n",
143
+ );
144
+ }
145
+ if (statement.kind === "return") return `return ${formatExpression(statement.value)}`;
146
+ return formatMutation(statement);
147
+ }
148
+
149
+ function formatRuleStatement(statement: PointSemanticRuleStatement): string[] {
150
+ if (statement.kind === "startsAt") return [` ${statement.name} starts at ${formatExpression(statement.value)}`];
151
+ if (statement.kind === "addWhen") return [` add ${formatExpression(statement.amount)} when ${formatExpression(statement.condition)}`];
152
+ if (statement.kind === "forEach") {
153
+ return [
154
+ ` for each ${statement.item} in ${formatExpression(statement.iterable)}`,
155
+ ...statement.body.map((mutation) => ` ${formatMutation(mutation)}`),
156
+ ];
157
+ }
158
+ if (statement.kind === "return") return [` return ${formatExpression(statement.value)}`];
159
+ return [` ${formatMutation(statement)}`];
160
+ }
161
+
162
+ function formatLabelStatement(statement: PointSemanticLabelStatement): string {
163
+ if (statement.kind === "whenReturn") return `when ${formatExpression(statement.condition)} return ${formatExpression(statement.value)}`;
164
+ return `otherwise return ${formatExpression(statement.value)}`;
165
+ }
166
+
167
+ function formatActionStatement(statement: PointSemanticActionStatement): string {
168
+ return `return ${formatExpression(statement.value)}`;
169
+ }
170
+
171
+ function formatPolicyStatement(statement: PointSemanticPolicyStatement): string {
172
+ if (statement.kind === "deny") return `deny ${formatExpression(statement.condition)}`;
173
+ if (statement.kind === "require") return `require ${formatExpression(statement.condition)}`;
174
+ return `allow ${formatExpression(statement.condition)}`;
175
+ }
176
+
177
+ function formatViewStatement(statement: PointSemanticViewStatement): string {
178
+ if (statement.kind === "whenRender") return `when ${formatExpression(statement.condition)} render ${formatExpression(statement.value)}`;
179
+ return `render ${formatExpression(statement.value)}`;
180
+ }
181
+
182
+ function formatRouteStatement(statement: PointSemanticRouteStatement): string {
183
+ return `return ${formatExpression(statement.value)}`;
184
+ }
185
+
186
+ function formatWorkflowStatement(statement: PointSemanticWorkflowStatement): string {
187
+ if (statement.kind === "step") return `step ${statement.name} is ${formatExpression(statement.value)}`;
188
+ return `return ${formatExpression(statement.value)}`;
189
+ }
190
+
191
+ function formatCommandStatement(statement: PointSemanticCommandStatement): string {
192
+ return `return ${formatExpression(statement.value)}`;
193
+ }
194
+
195
+ function formatMutation(statement: PointSemanticMutationStatement): string {
196
+ if (statement.kind === "addTo") return `add ${formatExpression(statement.amount)} to ${statement.target}`;
197
+ if (statement.kind === "subtractFrom") return `subtract ${formatExpression(statement.amount)} from ${statement.target}`;
198
+ return `set ${statement.target} to ${formatExpression(statement.value)}`;
199
+ }
200
+
201
+ function formatExpression(expression: PointSemanticExpression): string {
202
+ if (expression.kind === "literal") {
203
+ if (expression.value === null) return "none";
204
+ return JSON.stringify(expression.value);
205
+ }
206
+ if (expression.kind === "name") return expression.label;
207
+ if (expression.kind === "property") return `${formatExpression(expression.target)}.${expression.label}`;
208
+ if (expression.kind === "binary") return `${formatExpression(expression.left)} ${expression.operator} ${formatExpression(expression.right)}`;
209
+ if (expression.kind === "call") return `${expression.callee}(${expression.args.map(formatExpression).join(", ")})`;
210
+ if (expression.kind === "await") return `await ${formatExpression(expression.value)}`;
211
+ if (expression.kind === "list") return `[${expression.items.map(formatExpression).join(", ")}]`;
212
+ if (expression.kind === "record") {
213
+ return `{ ${expression.fields.map((field) => `${field.label}: ${formatExpression(field.value)}`).join(", ")} }`;
214
+ }
215
+ return `Error ${JSON.stringify(expression.message)}`;
216
+ }
217
+
218
+ function formatType(type: PointSemanticTypeExpression): string {
219
+ if (type.name === "Or") return type.args.map(formatType).join(" or ");
220
+ if (type.args.length === 0) return type.name;
221
+ return `${type.name}<${type.args.map(formatType).join(", ")}>`;
222
+ }
@@ -1,10 +1,10 @@
1
- export * from "./ast.ts";
2
- export * from "./callables.ts";
3
- export * from "./context.ts";
4
- export * from "./desugar.ts";
5
- export * from "./expressions.ts";
6
- export * from "./format.ts";
7
- export * from "./metadata.ts";
8
- export * from "./naming.ts";
9
- export * from "./parse.ts";
10
- export * from "./serialize.ts";
1
+ export * from "./ast.ts";
2
+ export * from "./callables.ts";
3
+ export * from "./context.ts";
4
+ export * from "./desugar.ts";
5
+ export * from "./expressions.ts";
6
+ export * from "./format.ts";
7
+ export * from "./metadata.ts";
8
+ export * from "./naming.ts";
9
+ export * from "./parse.ts";
10
+ export * from "./serialize.ts";
@@ -1,37 +1,37 @@
1
- import type { PointSemanticDeclarationMetadata } from "../core/ast.ts";
2
- import type { PointSemanticDeclaration } from "./ast.ts";
3
-
4
- export function semanticDeclarationMetadata(declaration: PointSemanticDeclaration): PointSemanticDeclarationMetadata {
5
- if (declaration.kind === "record") {
6
- return { kind: "record", name: declaration.name, outputName: undefined, effects: undefined };
7
- }
8
- if (declaration.kind === "external") {
9
- return { kind: "external", name: declaration.name, outputName: undefined, effects: undefined };
10
- }
11
- if (declaration.kind === "calculation" || declaration.kind === "rule" || declaration.kind === "action" || declaration.kind === "workflow" || declaration.kind === "command") {
12
- return {
13
- kind: declaration.kind,
14
- name: declaration.name,
15
- outputName: declaration.output.name,
16
- effects: declaration.kind === "action" ? declaration.touches : [],
17
- };
18
- }
19
- if (declaration.kind === "label") {
20
- return { kind: "label", name: declaration.name, outputName: declaration.output.name, effects: [] };
21
- }
22
- if (declaration.kind === "policy") {
23
- return { kind: "policy", name: declaration.name, outputName: "policy", effects: [] };
24
- }
25
- if (declaration.kind === "view") {
26
- return {
27
- kind: "view",
28
- name: declaration.name,
29
- outputName: declaration.output.name === "page" ? "view" : declaration.output.name,
30
- effects: [],
31
- };
32
- }
33
- if (declaration.kind === "route") {
34
- return { kind: "route", name: declaration.name, outputName: declaration.output.name, effects: [] };
35
- }
36
- throw new Error(`Unsupported semantic metadata for ${declaration.kind}`);
37
- }
1
+ import type { PointSemanticDeclarationMetadata } from "../core/ast.ts";
2
+ import type { PointSemanticDeclaration } from "./ast.ts";
3
+
4
+ export function semanticDeclarationMetadata(declaration: PointSemanticDeclaration): PointSemanticDeclarationMetadata {
5
+ if (declaration.kind === "record") {
6
+ return { kind: "record", name: declaration.name, outputName: undefined, effects: undefined };
7
+ }
8
+ if (declaration.kind === "external") {
9
+ return { kind: "external", name: declaration.name, outputName: undefined, effects: undefined };
10
+ }
11
+ if (declaration.kind === "calculation" || declaration.kind === "rule" || declaration.kind === "action" || declaration.kind === "workflow" || declaration.kind === "command") {
12
+ return {
13
+ kind: declaration.kind,
14
+ name: declaration.name,
15
+ outputName: declaration.output.name,
16
+ effects: declaration.kind === "action" ? declaration.touches : [],
17
+ };
18
+ }
19
+ if (declaration.kind === "label") {
20
+ return { kind: "label", name: declaration.name, outputName: declaration.output.name, effects: [] };
21
+ }
22
+ if (declaration.kind === "policy") {
23
+ return { kind: "policy", name: declaration.name, outputName: "policy", effects: [] };
24
+ }
25
+ if (declaration.kind === "view") {
26
+ return {
27
+ kind: "view",
28
+ name: declaration.name,
29
+ outputName: declaration.output.name === "page" ? "view" : declaration.output.name,
30
+ effects: [],
31
+ };
32
+ }
33
+ if (declaration.kind === "route") {
34
+ return { kind: "route", name: declaration.name, outputName: declaration.output.name, effects: [] };
35
+ }
36
+ throw new Error(`Unsupported semantic metadata for ${declaration.kind}`);
37
+ }
@@ -1,33 +1,33 @@
1
- export function toPascalCase(label: string): string {
2
- const words = label.match(/[A-Za-z0-9]+/g) ?? [];
3
- return words.map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`).join("");
4
- }
5
-
6
- export function toIdentifier(label: string): string {
7
- const words = label.match(/[A-Za-z0-9]+/g) ?? [];
8
- return words.map((word, index) => (index === 0 ? word.toLowerCase() : toPascalCase(word))).join("");
9
- }
10
-
11
- export function semanticFunctionName(
12
- label: string,
13
- outputName: string,
14
- kind: "calculation" | "rule" | "label" | "action" | "policy" | "view" | "route" | "workflow" | "command",
15
- ): string {
16
- const base = toIdentifier(label);
17
- const suffix =
18
- kind === "label"
19
- ? "Label"
20
- : kind === "policy"
21
- ? "Policy"
22
- : kind === "view"
23
- ? "View"
24
- : kind === "route"
25
- ? "Route"
26
- : kind === "workflow"
27
- ? "Workflow"
28
- : kind === "command"
29
- ? "Command"
30
- : toPascalCase(outputName);
31
- if (!suffix) return base;
32
- return base.toLowerCase().endsWith(suffix.toLowerCase()) ? base : `${base}${suffix}`;
33
- }
1
+ export function toPascalCase(label: string): string {
2
+ const words = label.match(/[A-Za-z0-9]+/g) ?? [];
3
+ return words.map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`).join("");
4
+ }
5
+
6
+ export function toIdentifier(label: string): string {
7
+ const words = label.match(/[A-Za-z0-9]+/g) ?? [];
8
+ return words.map((word, index) => (index === 0 ? word.toLowerCase() : toPascalCase(word))).join("");
9
+ }
10
+
11
+ export function semanticFunctionName(
12
+ label: string,
13
+ outputName: string,
14
+ kind: "calculation" | "rule" | "label" | "action" | "policy" | "view" | "route" | "workflow" | "command",
15
+ ): string {
16
+ const base = toIdentifier(label);
17
+ const suffix =
18
+ kind === "label"
19
+ ? "Label"
20
+ : kind === "policy"
21
+ ? "Policy"
22
+ : kind === "view"
23
+ ? "View"
24
+ : kind === "route"
25
+ ? "Route"
26
+ : kind === "workflow"
27
+ ? "Workflow"
28
+ : kind === "command"
29
+ ? "Command"
30
+ : toPascalCase(outputName);
31
+ if (!suffix) return base;
32
+ return base.toLowerCase().endsWith(suffix.toLowerCase()) ? base : `${base}${suffix}`;
33
+ }