@aventara/client 0.1.0-pilot.4 → 1.0.0-rc.1
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/CHANGELOG.md +679 -0
- package/README.md +168 -132
- package/dist/cli/command.parser.d.ts +6 -4
- package/dist/cli/command.parser.js +22 -11
- package/dist/cli/generate.command.d.ts +6 -1
- package/dist/cli/generate.command.js +12 -1
- package/dist/cli/generation-failure.renderer.js +24 -24
- package/dist/cli/step.reporter.d.ts +31 -0
- package/dist/cli/step.reporter.js +87 -0
- package/dist/cli.js +2 -0
- package/dist/config/client-config.interface.d.ts +7 -7
- package/dist/config/config.loader.d.ts +4 -4
- package/dist/config/config.loader.js +7 -7
- package/dist/config/config.resolver.d.ts +7 -7
- package/dist/config/config.resolver.js +12 -12
- package/dist/config/env.cascade.d.ts +2 -2
- package/dist/config/env.cascade.js +4 -4
- package/dist/config/module-style.resolver.d.ts +1 -1
- package/dist/config/module-style.resolver.js +2 -2
- package/dist/config/tsconfig.locator.d.ts +1 -1
- package/dist/config/tsconfig.locator.js +2 -2
- package/dist/contract/contract.acceptance.d.ts +4 -4
- package/dist/contract/contract.acceptance.js +4 -4
- package/dist/contract/contract.fetcher.d.ts +3 -3
- package/dist/contract/contract.fetcher.js +6 -6
- package/dist/contract/contract.loader.d.ts +6 -6
- package/dist/contract/contract.loader.js +2 -2
- package/dist/emit/client-surface.emitter.d.ts +2 -2
- package/dist/emit/client-surface.emitter.js +77 -43
- package/dist/emit/client-tree.emitter.d.ts +3 -3
- package/dist/emit/client-tree.emitter.js +8 -5
- package/dist/emit/contract-carrier.emitter.d.ts +3 -3
- package/dist/emit/contract-carrier.emitter.js +1 -1
- package/dist/emit/derivation.emitter.js +1 -0
- package/dist/emit/descriptor.emitter.d.ts +2 -2
- package/dist/emit/descriptor.emitter.js +2 -2
- package/dist/emit/emitted-tree.interface.d.ts +1 -1
- package/dist/emit/enum.emitter.d.ts +2 -2
- package/dist/emit/field-check.emitter.d.ts +21 -0
- package/dist/emit/field-check.emitter.js +603 -0
- package/dist/emit/json-shape.emitter.d.ts +16 -0
- package/dist/emit/json-shape.emitter.js +88 -0
- package/dist/emit/name.deriver.d.ts +6 -6
- package/dist/emit/name.deriver.js +15 -15
- package/dist/emit/named-type.emitter.d.ts +2 -2
- package/dist/emit/runtime.emitter.d.ts +2 -2
- package/dist/emit/runtime.emitter.js +117 -112
- package/dist/emit/scalar.codec.d.ts +1 -1
- package/dist/emit/scalar.codec.js +78 -35
- package/dist/emit/transaction.emitter.js +131 -83
- package/dist/generate.d.ts +11 -3
- package/dist/generate.js +40 -26
- package/dist/index.d.ts +1 -1
- package/dist/init/client-init.errors.d.ts +4 -4
- package/dist/init/client-init.errors.js +4 -4
- package/dist/init/client-init.orchestrator.js +37 -22
- package/dist/init/client-init.questions.d.ts +5 -5
- package/dist/init/client-init.questions.js +10 -10
- package/dist/init/client-project.inspector.d.ts +2 -2
- package/dist/init/client-project.inspector.js +3 -3
- package/dist/init/command.runner.d.ts +2 -0
- package/dist/init/command.runner.js +4 -1
- package/dist/output/output.writer.d.ts +5 -5
- package/dist/output/output.writer.js +12 -12
- package/package.json +6 -5
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const SCALAR_TYPES = {
|
|
2
|
+
string: "string",
|
|
3
|
+
number: "number",
|
|
4
|
+
integer: "number",
|
|
5
|
+
boolean: "boolean",
|
|
6
|
+
null: "null",
|
|
7
|
+
};
|
|
8
|
+
const plain = (text) => ({ text, union: false });
|
|
9
|
+
function unionOf(members) {
|
|
10
|
+
return members.length === 1
|
|
11
|
+
? members[0]
|
|
12
|
+
: { text: members.map((member) => member.text).join(" | "), union: true };
|
|
13
|
+
}
|
|
14
|
+
function operand(type) {
|
|
15
|
+
return type.union ? `(${type.text})` : type.text;
|
|
16
|
+
}
|
|
17
|
+
function emitted(schema) {
|
|
18
|
+
if (Object.hasOwn(schema, "const")) {
|
|
19
|
+
return plain(JSON.stringify(schema.const));
|
|
20
|
+
}
|
|
21
|
+
if (Array.isArray(schema.enum)) {
|
|
22
|
+
return unionOf(schema.enum.map((value) => plain(JSON.stringify(value))));
|
|
23
|
+
}
|
|
24
|
+
for (const keyword of ["anyOf", "oneOf"]) {
|
|
25
|
+
const options = schema[keyword];
|
|
26
|
+
if (Array.isArray(options)) {
|
|
27
|
+
return unionOf(options.map((option) => emitted(option)));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const type = schema.type;
|
|
31
|
+
if (typeof type === "string" && Object.hasOwn(SCALAR_TYPES, type)) {
|
|
32
|
+
return plain(SCALAR_TYPES[type]);
|
|
33
|
+
}
|
|
34
|
+
if (type === "array") {
|
|
35
|
+
if (Array.isArray(schema.prefixItems)) {
|
|
36
|
+
return plain(`[${schema.prefixItems.map((item) => emitted(item).text).join(", ")}]`);
|
|
37
|
+
}
|
|
38
|
+
return plain(`${operand(emitted(schema.items))}[]`);
|
|
39
|
+
}
|
|
40
|
+
if (type === "object") {
|
|
41
|
+
const properties = schema.properties;
|
|
42
|
+
if (properties === undefined) {
|
|
43
|
+
return plain(`{ [key: string]: ${emitted(schema.additionalProperties).text} }`);
|
|
44
|
+
}
|
|
45
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
46
|
+
const members = Object.keys(properties).map((key) => {
|
|
47
|
+
const member = emitted(properties[key]).text;
|
|
48
|
+
return required.has(key)
|
|
49
|
+
? `${JSON.stringify(key)}: ${member}`
|
|
50
|
+
: `${JSON.stringify(key)}?: ${member} | undefined`;
|
|
51
|
+
});
|
|
52
|
+
return plain(members.length === 0 ? "{}" : `{ ${members.join("; ")} }`);
|
|
53
|
+
}
|
|
54
|
+
throw new Error(`a Json Shape schema outside the accepted forms reached the emitter: ${JSON.stringify(schema)}`);
|
|
55
|
+
}
|
|
56
|
+
export function jsonSchemaType(schema) {
|
|
57
|
+
return emitted(schema).text;
|
|
58
|
+
}
|
|
59
|
+
export function shapedContractType(contract) {
|
|
60
|
+
const order = (keys) => [...keys].sort((left, right) => (left < right ? -1 : left > right ? 1 : 0));
|
|
61
|
+
const resources = order(Object.keys(contract.resources)).flatMap((resourceName) => {
|
|
62
|
+
const fields = contract.resources[resourceName]?.fields ?? {};
|
|
63
|
+
const shaped = order(Object.keys(fields)).flatMap((fieldName) => {
|
|
64
|
+
const field = fields[fieldName];
|
|
65
|
+
return field?.kind === "scalar" && field.json !== undefined
|
|
66
|
+
? [
|
|
67
|
+
`\t\t\t\treadonly ${JSON.stringify(fieldName)}: { readonly json: JsonFieldType<${jsonSchemaType(field.json)}> };\n`,
|
|
68
|
+
]
|
|
69
|
+
: [];
|
|
70
|
+
});
|
|
71
|
+
return shaped.length === 0
|
|
72
|
+
? []
|
|
73
|
+
: [
|
|
74
|
+
`\t\treadonly ${JSON.stringify(resourceName)}: {\n` +
|
|
75
|
+
"\t\t\treadonly fields: {\n" +
|
|
76
|
+
shaped.join("") +
|
|
77
|
+
"\t\t\t};\n" +
|
|
78
|
+
"\t\t};\n",
|
|
79
|
+
];
|
|
80
|
+
});
|
|
81
|
+
return resources.length === 0
|
|
82
|
+
? undefined
|
|
83
|
+
: "ClientContractShape & {\n" +
|
|
84
|
+
"\treadonly resources: {\n" +
|
|
85
|
+
resources.join("") +
|
|
86
|
+
"\t};\n" +
|
|
87
|
+
"}";
|
|
88
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AvContractClient, AvOperationFamily } from "@aventara/core";
|
|
2
2
|
/**
|
|
3
3
|
* Name derivation and the rename ladder for the emitted tree.
|
|
4
4
|
*/
|
|
5
5
|
export declare const RESERVED_EMITTED_NAMES: readonly string[];
|
|
6
6
|
export interface ResourceNamedType {
|
|
7
7
|
readonly suffix: string;
|
|
8
|
-
readonly family:
|
|
8
|
+
readonly family: AvOperationFamily;
|
|
9
9
|
readonly variant: string;
|
|
10
10
|
/** The argument it names; absent for `X`, the default record. */
|
|
11
11
|
readonly argument?: "where" | "orderBy" | "data" | "select" | "include";
|
|
@@ -43,12 +43,12 @@ export declare function isIdentifierName(text: string): boolean;
|
|
|
43
43
|
* The emitted names of a Contract's enums and Resources, renamed where a name
|
|
44
44
|
* cannot be declared as-is.
|
|
45
45
|
*
|
|
46
|
-
* @throws
|
|
46
|
+
* @throws AvGeneratedNameError naming every name no rung of its ladder can repair.
|
|
47
47
|
*/
|
|
48
|
-
export declare function deriveEmittedNames(contract: Pick<
|
|
48
|
+
export declare function deriveEmittedNames(contract: Pick<AvContractClient, "enums" | "resources">): EmittedNames;
|
|
49
49
|
/** The refusal that stops generation over names no rename can repair. */
|
|
50
|
-
export declare class
|
|
51
|
-
readonly name = "
|
|
50
|
+
export declare class AvGeneratedNameError extends Error {
|
|
51
|
+
readonly name = "AvGeneratedNameError";
|
|
52
52
|
constructor(problems: readonly string[]);
|
|
53
53
|
}
|
|
54
54
|
export declare function ownPropertyKey(value: string): string;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { isOperationVariantAvailable
|
|
1
|
+
import { isOperationVariantAvailable } from "@aventara/core/internal";
|
|
2
2
|
import { FRAMEWORK_ERROR_CLASS_NAMES } from "./runtime.emitter.js";
|
|
3
3
|
export const RESERVED_EMITTED_NAMES = [
|
|
4
4
|
...new Set([
|
|
5
5
|
"AvClient",
|
|
6
6
|
"AvClientOptions",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
7
|
+
"AvCallOptions",
|
|
8
|
+
"AvCause",
|
|
9
|
+
"AvDecimal",
|
|
10
|
+
"AvFetch",
|
|
11
|
+
"AvError",
|
|
12
|
+
"AvNotFoundError",
|
|
13
|
+
"AvOperation",
|
|
14
|
+
"AvOperationCode",
|
|
15
15
|
"ResourceArgument",
|
|
16
16
|
"ResourceRecord",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
17
|
+
"AvTransportError",
|
|
18
|
+
"AvValidationCode",
|
|
19
|
+
"AvValidationIssue",
|
|
20
20
|
"avClient",
|
|
21
21
|
...FRAMEWORK_ERROR_CLASS_NAMES,
|
|
22
22
|
]),
|
|
@@ -214,7 +214,7 @@ export function deriveEmittedNames(contract) {
|
|
|
214
214
|
const enums = enumNames.map((name) => resolve("enum", name));
|
|
215
215
|
const properties = resourceProperties(resourceNames, warnings, refusals);
|
|
216
216
|
if (refusals.length > 0) {
|
|
217
|
-
throw new
|
|
217
|
+
throw new AvGeneratedNameError(byName(refusals));
|
|
218
218
|
}
|
|
219
219
|
return { enums, resources, properties, warnings: byName(warnings) };
|
|
220
220
|
}
|
|
@@ -262,8 +262,8 @@ function byName(lines) {
|
|
|
262
262
|
function compareCodeUnits(left, right) {
|
|
263
263
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
264
264
|
}
|
|
265
|
-
export class
|
|
266
|
-
name = "
|
|
265
|
+
export class AvGeneratedNameError extends Error {
|
|
266
|
+
name = "AvGeneratedNameError";
|
|
267
267
|
constructor(problems) {
|
|
268
268
|
super(`the ClientContract's names cannot all be emitted: ${problems.join("; ")}. ` +
|
|
269
269
|
`Rename ${problems.length === 1 ? "it" : "them"} on the server, then generate again.`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AvContractClient } from "@aventara/core";
|
|
2
2
|
import type { EmittedModule } from "./emitted-tree.interface.js";
|
|
3
3
|
import { type ClientModuleStyle } from "./module-style.interface.js";
|
|
4
4
|
import { type EmittedNames } from "./name.deriver.js";
|
|
5
|
-
export declare function emitNamedTypesModule(contract:
|
|
5
|
+
export declare function emitNamedTypesModule(contract: AvContractClient, names: EmittedNames, style: ClientModuleStyle): EmittedModule;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AvContractClient } from "@aventara/core";
|
|
2
2
|
import type { ClientEntrypoint } from "../config/client-config.interface.js";
|
|
3
3
|
import type { EmittedModule } from "./emitted-tree.interface.js";
|
|
4
4
|
import { type ClientModuleStyle } from "./module-style.interface.js";
|
|
5
5
|
export declare function emitDecimalModule(): EmittedModule;
|
|
6
|
-
export declare function emitMetadataModule(protocol:
|
|
6
|
+
export declare function emitMetadataModule(protocol: AvContractClient["protocol"], entrypoint: ClientEntrypoint): EmittedModule;
|
|
7
7
|
export declare const FRAMEWORK_ERROR_CLASS_NAMES: readonly string[];
|
|
8
8
|
export declare function errorsModuleExports(): readonly string[];
|
|
9
9
|
export declare function emitErrorsModule(): EmittedModule;
|