reactivated 0.30.2 → 0.31.0
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/components/Widget.d.ts +0 -1
- package/dist/components/Widget.js +0 -13
- package/dist/components/Widget.js.map +1 -1
- package/dist/eslintrc.js +3 -0
- package/dist/eslintrc.js.map +1 -1
- package/dist/forms/index.d.ts +31 -13
- package/dist/forms/index.js +89 -29
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/widgets.d.ts +2 -0
- package/dist/forms/widgets.js +1 -1
- package/dist/forms/widgets.js.map +1 -1
- package/dist/generated.d.ts +10 -0
- package/dist/generator.mjs +143 -5
- package/dist/generator.mjs.map +1 -1
- package/dist/rpc.d.ts +58 -0
- package/dist/rpc.js +126 -0
- package/dist/rpc.js.map +1 -0
- package/package.json +2 -1
- package/scripts/setup_environment.sh +6 -2
- package/src/components/Widget.tsx +0 -13
- package/src/eslintrc.tsx +4 -0
- package/src/forms/index.tsx +154 -43
- package/src/forms/widgets.tsx +4 -1
- package/src/generated.tsx +10 -0
- package/src/generator.mts +171 -4
- package/src/rpc.tsx +207 -0
package/src/forms/index.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import produce,
|
|
1
|
+
import {produce, castDraft} from "immer";
|
|
2
2
|
import {FileInfoResult} from "prettier";
|
|
3
3
|
import React from "react";
|
|
4
4
|
|
|
@@ -79,6 +79,7 @@ export interface FormHandler<T extends FieldMap> {
|
|
|
79
79
|
nonFieldErrors: string[] | null;
|
|
80
80
|
|
|
81
81
|
setValue: <K extends keyof T>(name: K, value: FormValues<T>[K]) => void;
|
|
82
|
+
setValues: (values: FormValues<T>) => void;
|
|
82
83
|
setErrors: (errors: FormErrors<T>) => void;
|
|
83
84
|
iterate: (
|
|
84
85
|
iterator: Array<Extract<keyof T, string>>,
|
|
@@ -116,16 +117,15 @@ export const getInitialFormState = <T extends FieldMap>(form: FormLike<T>) => {
|
|
|
116
117
|
|
|
117
118
|
export const getInitialFormSetState = <T extends FieldMap>(
|
|
118
119
|
forms: Array<FormLike<T>>,
|
|
120
|
+
initial?: FormValues<T>[],
|
|
119
121
|
) => {
|
|
120
|
-
return
|
|
121
|
-
forms.map((form) => [form.prefix, getInitialFormState(form)] as const),
|
|
122
|
-
);
|
|
122
|
+
return forms.map((form, index) => initial?.[index] ?? getInitialFormState(form));
|
|
123
123
|
};
|
|
124
124
|
|
|
125
125
|
export const getInitialFormSetErrors = <T extends FieldMap>(
|
|
126
126
|
forms: Array<FormLike<T>>,
|
|
127
127
|
) => {
|
|
128
|
-
return
|
|
128
|
+
return forms.map((form, index) => form.errors);
|
|
129
129
|
};
|
|
130
130
|
|
|
131
131
|
export const getFormHandler = <T extends FieldMap>({
|
|
@@ -311,6 +311,9 @@ export const getFormHandler = <T extends FieldMap>({
|
|
|
311
311
|
iterate,
|
|
312
312
|
reset,
|
|
313
313
|
setErrors,
|
|
314
|
+
setValues: (values) => {
|
|
315
|
+
setValues(() => values);
|
|
316
|
+
},
|
|
314
317
|
setValue: (fieldName, value) => {
|
|
315
318
|
changeValues(fieldName, (prevValues) => ({
|
|
316
319
|
...prevValues,
|
|
@@ -320,23 +323,34 @@ export const getFormHandler = <T extends FieldMap>({
|
|
|
320
323
|
};
|
|
321
324
|
};
|
|
322
325
|
|
|
323
|
-
export const useForm = <
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
326
|
+
export const useForm = <
|
|
327
|
+
T extends FieldMap,
|
|
328
|
+
S extends Array<keyof T> = [],
|
|
329
|
+
R extends {[P in Exclude<keyof T, S[number]>]: T[P]} = {
|
|
330
|
+
[P in Exclude<keyof T, S[number]>]: T[P];
|
|
331
|
+
},
|
|
332
|
+
>(options: {
|
|
327
333
|
form: FormLike<T>;
|
|
334
|
+
initial?: Partial<FormValues<R>>;
|
|
335
|
+
exclude?: [...S];
|
|
328
336
|
fieldInterceptor?: (
|
|
329
|
-
fieldName: keyof
|
|
330
|
-
field: FieldHandler<
|
|
331
|
-
values: FormValues<
|
|
337
|
+
fieldName: keyof R,
|
|
338
|
+
field: FieldHandler<R[keyof R]["widget"]>,
|
|
339
|
+
values: FormValues<R>,
|
|
332
340
|
) => typeof field;
|
|
333
341
|
changeInterceptor?: (
|
|
334
|
-
name: keyof
|
|
335
|
-
prevValues: FormValues<
|
|
336
|
-
nextValues: FormValues<
|
|
337
|
-
) => FormValues<
|
|
338
|
-
}): FormHandler<
|
|
339
|
-
const
|
|
342
|
+
name: keyof R,
|
|
343
|
+
prevValues: FormValues<R>,
|
|
344
|
+
nextValues: FormValues<R>,
|
|
345
|
+
) => FormValues<R>;
|
|
346
|
+
}): FormHandler<R> => {
|
|
347
|
+
const form = {
|
|
348
|
+
...(options.form as any as FormLike<R>),
|
|
349
|
+
iterator: options.form.iterator.filter(
|
|
350
|
+
(field) => options.exclude == null || !options.exclude.includes(field),
|
|
351
|
+
),
|
|
352
|
+
} as any as FormLike<R>;
|
|
353
|
+
const initial = {...getInitialFormState(form), ...options.initial};
|
|
340
354
|
const [values, formSetValues] = React.useState(initial);
|
|
341
355
|
const [errors, setErrors] = React.useState(form.errors);
|
|
342
356
|
|
|
@@ -492,11 +506,19 @@ export const Widget = (props: {field: FieldHandler<widgets.CoreWidget>}) => {
|
|
|
492
506
|
onChange={field.handler}
|
|
493
507
|
/>
|
|
494
508
|
);
|
|
509
|
+
} else if (field.tag === "django.forms.widgets.PasswordInput") {
|
|
510
|
+
return (
|
|
511
|
+
<widgets.TextInput
|
|
512
|
+
name={field.name}
|
|
513
|
+
value={field.value}
|
|
514
|
+
onChange={field.handler}
|
|
515
|
+
type="password"
|
|
516
|
+
/>
|
|
517
|
+
);
|
|
495
518
|
} else if (
|
|
496
519
|
field.tag === "django.forms.widgets.TextInput" ||
|
|
497
520
|
field.tag === "django.forms.widgets.DateInput" ||
|
|
498
521
|
field.tag === "django.forms.widgets.URLInput" ||
|
|
499
|
-
field.tag === "django.forms.widgets.PasswordInput" ||
|
|
500
522
|
field.tag === "django.forms.widgets.EmailInput" ||
|
|
501
523
|
field.tag === "django.forms.widgets.TimeInput" ||
|
|
502
524
|
field.tag === "django.forms.widgets.NumberInput"
|
|
@@ -506,6 +528,7 @@ export const Widget = (props: {field: FieldHandler<widgets.CoreWidget>}) => {
|
|
|
506
528
|
name={field.name}
|
|
507
529
|
value={field.value}
|
|
508
530
|
onChange={field.handler}
|
|
531
|
+
placeholder={field.widget.attrs.placeholder}
|
|
509
532
|
/>
|
|
510
533
|
);
|
|
511
534
|
} else if (field.tag === "django.forms.widgets.Select") {
|
|
@@ -573,6 +596,7 @@ export const ManagementForm = <T extends FieldMap>({
|
|
|
573
596
|
export const useFormSet = <T extends FieldMap>(options: {
|
|
574
597
|
formSet: FormSetLike<T>;
|
|
575
598
|
onAddForm?: (form: FormLike<T>) => void;
|
|
599
|
+
initial?: FormValues<T>[];
|
|
576
600
|
fieldInterceptor?: (
|
|
577
601
|
fieldName: keyof T,
|
|
578
602
|
field: FieldHandler<T[keyof T]["widget"]>,
|
|
@@ -584,14 +608,40 @@ export const useFormSet = <T extends FieldMap>(options: {
|
|
|
584
608
|
nextValues: FormValues<T>,
|
|
585
609
|
) => FormValues<T>;
|
|
586
610
|
}) => {
|
|
587
|
-
const
|
|
611
|
+
const createForm = (index: number) => {
|
|
612
|
+
return produce(options.formSet.empty_form, (draftState) => {
|
|
613
|
+
for (const fieldName of draftState.iterator) {
|
|
614
|
+
const prefix = `${options.formSet.prefix}-${index}`;
|
|
615
|
+
const field = draftState.fields[fieldName];
|
|
616
|
+
const htmlName = `${prefix}-${field.name}`;
|
|
617
|
+
draftState.fields[fieldName].widget.name = htmlName;
|
|
618
|
+
draftState.fields[fieldName].widget.attrs.id = `id_${htmlName}`;
|
|
619
|
+
draftState.prefix = prefix;
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
const formSetFromInitialValues = produce(options.formSet, (draftState) => {
|
|
625
|
+
if (options.initial == null) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
draftState.total_form_count = options.initial.length;
|
|
629
|
+
draftState.forms = options.initial.map((_, index) => {
|
|
630
|
+
return castDraft(createForm(index));
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
const [formSet, setFormSet] = React.useState(formSetFromInitialValues);
|
|
588
635
|
|
|
589
|
-
const initialFormSetState = getInitialFormSetState(
|
|
636
|
+
const initialFormSetState = getInitialFormSetState(
|
|
637
|
+
formSetFromInitialValues.forms,
|
|
638
|
+
options.initial,
|
|
639
|
+
);
|
|
590
640
|
const initialFormSetErrors = getInitialFormSetErrors(options.formSet.forms);
|
|
591
641
|
const [values, formSetSetValues] =
|
|
592
|
-
React.useState<
|
|
642
|
+
React.useState<typeof initialFormSetState>(initialFormSetState);
|
|
593
643
|
const [errors, formSetSetErrors] =
|
|
594
|
-
React.useState<
|
|
644
|
+
React.useState<typeof initialFormSetErrors>(initialFormSetErrors);
|
|
595
645
|
|
|
596
646
|
const emptyFormValues = getInitialFormState(formSet.empty_form);
|
|
597
647
|
|
|
@@ -600,24 +650,23 @@ export const useFormSet = <T extends FieldMap>(options: {
|
|
|
600
650
|
form,
|
|
601
651
|
changeInterceptor: options.changeInterceptor,
|
|
602
652
|
fieldInterceptor: options.fieldInterceptor,
|
|
603
|
-
values: values[
|
|
604
|
-
errors: errors[
|
|
653
|
+
values: values[index] ?? emptyFormValues,
|
|
654
|
+
errors: errors[index] ?? {},
|
|
605
655
|
setErrors: (nextErrors) => {
|
|
606
656
|
formSetSetErrors((prevErrors) => ({
|
|
607
657
|
...prevErrors,
|
|
608
|
-
[
|
|
658
|
+
[index]: nextErrors,
|
|
609
659
|
}));
|
|
610
660
|
},
|
|
611
661
|
initial: initialFormSetState[index] ?? emptyFormValues,
|
|
612
662
|
setValues: (getValuesToSetFromPrevValues) => {
|
|
613
663
|
formSetSetValues((prevValues) => {
|
|
614
664
|
const nextValues = getValuesToSetFromPrevValues(
|
|
615
|
-
prevValues[
|
|
665
|
+
prevValues[index] ?? emptyFormValues,
|
|
616
666
|
);
|
|
617
|
-
return {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
};
|
|
667
|
+
return produce(prevValues, (draftState) => {
|
|
668
|
+
draftState[index] = castDraft(nextValues);
|
|
669
|
+
});
|
|
621
670
|
});
|
|
622
671
|
},
|
|
623
672
|
});
|
|
@@ -625,18 +674,9 @@ export const useFormSet = <T extends FieldMap>(options: {
|
|
|
625
674
|
|
|
626
675
|
const addForm = () => {
|
|
627
676
|
const {total_form_count} = formSet;
|
|
628
|
-
type AdditionalForm = (typeof formSet)["forms"][number];
|
|
629
677
|
|
|
630
|
-
const extraForm =
|
|
631
|
-
|
|
632
|
-
const prefix = `${formSet.prefix}-${formSet.total_form_count}`;
|
|
633
|
-
const field = draftState.fields[fieldName];
|
|
634
|
-
const htmlName = `${prefix}-${field.name}`;
|
|
635
|
-
draftState.fields[fieldName].widget.name = htmlName;
|
|
636
|
-
draftState.fields[fieldName].widget.attrs.id = `id_${htmlName}`;
|
|
637
|
-
draftState.prefix = prefix;
|
|
638
|
-
}
|
|
639
|
-
});
|
|
678
|
+
const extraForm = createForm(formSet.total_form_count);
|
|
679
|
+
|
|
640
680
|
const updated = produce(formSet, (draftState) => {
|
|
641
681
|
draftState.forms.push(castDraft(extraForm));
|
|
642
682
|
draftState.total_form_count += 1;
|
|
@@ -646,7 +686,38 @@ export const useFormSet = <T extends FieldMap>(options: {
|
|
|
646
686
|
options.onAddForm?.(extraForm);
|
|
647
687
|
};
|
|
648
688
|
|
|
649
|
-
|
|
689
|
+
const clear = () => {
|
|
690
|
+
setFormSet(
|
|
691
|
+
produce(formSet, (draftState) => {
|
|
692
|
+
formSetSetValues([]);
|
|
693
|
+
draftState.forms = [];
|
|
694
|
+
draftState.total_form_count = 0;
|
|
695
|
+
}),
|
|
696
|
+
);
|
|
697
|
+
};
|
|
698
|
+
|
|
699
|
+
const setFormsAndValues = (values: FormValues<T>[]) => {
|
|
700
|
+
formSetSetValues(values);
|
|
701
|
+
|
|
702
|
+
const updated = produce(formSet, (draftState) => {
|
|
703
|
+
draftState.total_form_count = values.length;
|
|
704
|
+
draftState.forms = values.map((_, index) => {
|
|
705
|
+
return castDraft(createForm(index));
|
|
706
|
+
});
|
|
707
|
+
});
|
|
708
|
+
setFormSet(updated);
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
return {
|
|
712
|
+
schema: formSet,
|
|
713
|
+
values,
|
|
714
|
+
forms,
|
|
715
|
+
addForm,
|
|
716
|
+
clear,
|
|
717
|
+
setFormsAndValues,
|
|
718
|
+
setErrors: formSetSetErrors,
|
|
719
|
+
setValues: formSetSetValues,
|
|
720
|
+
};
|
|
650
721
|
};
|
|
651
722
|
|
|
652
723
|
export const bindWidgetType = <W extends WidgetLike>() => {
|
|
@@ -767,3 +838,43 @@ export const FormSet = <T extends FieldMap<widgets.CoreWidget>>(props: {
|
|
|
767
838
|
</>
|
|
768
839
|
);
|
|
769
840
|
};
|
|
841
|
+
|
|
842
|
+
export type UnknownFormValues<T extends FieldMap> = {
|
|
843
|
+
[K in keyof T]: T[K] extends {enum: unknown} ? T[K]["enum"] | null : unknown;
|
|
844
|
+
};
|
|
845
|
+
|
|
846
|
+
// TODO: Should be T extends Record<string, FormLike<any> | FormSetLike<any>>
|
|
847
|
+
// but jsonschema outputs interfaces instead of types. Figure out how to output a type.
|
|
848
|
+
export type FormOrFormSetValues<T> = T extends {tag: "FormGroup"}
|
|
849
|
+
? Omit<{[K in keyof T]: FormOrFormSetValues<T[K]>}, "tag">
|
|
850
|
+
: T extends FormLike<any>
|
|
851
|
+
? UnknownFormValues<T["fields"]>
|
|
852
|
+
: T extends FormSetLike<any>
|
|
853
|
+
? Array<UnknownFormValues<T["empty_form"]["fields"]>>
|
|
854
|
+
: T extends null
|
|
855
|
+
? null
|
|
856
|
+
: never;
|
|
857
|
+
|
|
858
|
+
export type FormOrFormSetErrors<T> = T extends {tag: "FormGroup"}
|
|
859
|
+
? Omit<{[K in keyof T]?: FormOrFormSetErrors<T[K]>}, "tag">
|
|
860
|
+
: T extends FormLike<any>
|
|
861
|
+
? NonNullable<T["errors"]>
|
|
862
|
+
: T extends FormSetLike<any>
|
|
863
|
+
? Array<NonNullable<T["empty_form"]["errors"]>>
|
|
864
|
+
: T extends null
|
|
865
|
+
? null
|
|
866
|
+
: never;
|
|
867
|
+
|
|
868
|
+
// Used by Joy, but unsure what this is for.
|
|
869
|
+
export const getValue = (optgroup: Optgroup) => {
|
|
870
|
+
const rawValue = optgroup[1][0].value;
|
|
871
|
+
|
|
872
|
+
if (rawValue == null) {
|
|
873
|
+
return "";
|
|
874
|
+
} else if (rawValue === true) {
|
|
875
|
+
return "True";
|
|
876
|
+
} else if (rawValue === false) {
|
|
877
|
+
return "False";
|
|
878
|
+
}
|
|
879
|
+
return rawValue;
|
|
880
|
+
};
|
package/src/forms/widgets.tsx
CHANGED
|
@@ -27,12 +27,15 @@ export const TextInput = (props: {
|
|
|
27
27
|
className?: string;
|
|
28
28
|
value: string | null;
|
|
29
29
|
onChange: (value: string) => void;
|
|
30
|
+
placeholder?: string;
|
|
31
|
+
type?: "text" | "password";
|
|
30
32
|
}) => {
|
|
31
33
|
return (
|
|
32
34
|
<input
|
|
33
|
-
type="text"
|
|
35
|
+
type={props.type ?? "text"}
|
|
34
36
|
name={props.name}
|
|
35
37
|
className={props.className}
|
|
38
|
+
placeholder={props.placeholder}
|
|
36
39
|
value={props.value ?? ""}
|
|
37
40
|
onChange={(event) => props.onChange(event.target.value)}
|
|
38
41
|
/>
|
package/src/generated.tsx
CHANGED
|
@@ -30,6 +30,9 @@ export interface Types {
|
|
|
30
30
|
URLSchema: {
|
|
31
31
|
[k: string]: ReactivatedTypesURL;
|
|
32
32
|
};
|
|
33
|
+
RPCRegistry: {
|
|
34
|
+
[k: string]: ReactivatedTypesRPC;
|
|
35
|
+
};
|
|
33
36
|
}
|
|
34
37
|
export interface DjangoFormsWidgetsHiddenInput {
|
|
35
38
|
template_name: "django/forms/widgets/hidden.html";
|
|
@@ -277,3 +280,10 @@ export interface ReactivatedTypesURL {
|
|
|
277
280
|
[k: string]: string;
|
|
278
281
|
};
|
|
279
282
|
}
|
|
283
|
+
export interface ReactivatedTypesRPC {
|
|
284
|
+
params: [string, string][];
|
|
285
|
+
url: string;
|
|
286
|
+
input: string | null;
|
|
287
|
+
output: string;
|
|
288
|
+
type: "form" | "form_set" | "form_group";
|
|
289
|
+
}
|
package/src/generator.mts
CHANGED
|
@@ -10,7 +10,9 @@ const stdinBuffer = fs.readFileSync(0);
|
|
|
10
10
|
const {compile} = await import("json-schema-to-typescript");
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
|
+
CodeBlockWriter,
|
|
13
14
|
Project,
|
|
15
|
+
Scope,
|
|
14
16
|
SourceFile,
|
|
15
17
|
StructureKind,
|
|
16
18
|
SyntaxKind,
|
|
@@ -20,7 +22,16 @@ import {
|
|
|
20
22
|
} from "ts-morph";
|
|
21
23
|
|
|
22
24
|
const schema = JSON.parse(stdinBuffer.toString("utf8"));
|
|
23
|
-
const {
|
|
25
|
+
const {
|
|
26
|
+
urls: possibleEmptyUrls,
|
|
27
|
+
templates,
|
|
28
|
+
interfaces,
|
|
29
|
+
rpc: uncastedRpc,
|
|
30
|
+
types,
|
|
31
|
+
values,
|
|
32
|
+
} = schema;
|
|
33
|
+
|
|
34
|
+
const rpc: generated.Types["RPCRegistry"] = uncastedRpc;
|
|
24
35
|
|
|
25
36
|
const urls: generated.Types["URLSchema"] = {
|
|
26
37
|
...possibleEmptyUrls,
|
|
@@ -40,6 +51,154 @@ const project = new Project();
|
|
|
40
51
|
|
|
41
52
|
const sourceFile = project.createSourceFile("");
|
|
42
53
|
|
|
54
|
+
const classDeclaration = sourceFile.addClass({
|
|
55
|
+
name: "RPC",
|
|
56
|
+
isExported: true,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const rpcConstructor = classDeclaration.addConstructor({
|
|
60
|
+
parameters: [{name: "requester", type: "rpcUtils.Requester", scope: Scope.Public}],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
let rpcConstructorBody = "";
|
|
64
|
+
|
|
65
|
+
for (const name of Object.keys(rpc)) {
|
|
66
|
+
const {url, input, output, type, params} = rpc[name];
|
|
67
|
+
const functionDeclaration = classDeclaration.addMethod({
|
|
68
|
+
name,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
rpcConstructorBody += `this.${name} = (this.${name} as any).bind(this);\n`;
|
|
72
|
+
functionDeclaration.setIsAsync(true);
|
|
73
|
+
|
|
74
|
+
functionDeclaration.addParameter({
|
|
75
|
+
name: "this",
|
|
76
|
+
type: "void",
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
let bodyText = "";
|
|
80
|
+
const initializer = {
|
|
81
|
+
url: (writer: CodeBlockWriter) => writer.quote(url),
|
|
82
|
+
name: (writer: CodeBlockWriter) => writer.quote(name),
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
if (params.length >= 1) {
|
|
86
|
+
const paramsInterface = functionDeclaration.addInterface({
|
|
87
|
+
name: "WILL_BE_STRIPPED",
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const iterator = [];
|
|
91
|
+
for (const [paramType, paramName] of params) {
|
|
92
|
+
paramsInterface.addProperty({name: paramName, type: "string | number"});
|
|
93
|
+
iterator.push(paramName);
|
|
94
|
+
}
|
|
95
|
+
functionDeclaration.addParameter({
|
|
96
|
+
name: "params",
|
|
97
|
+
type: paramsInterface.getText().replace("interface WILL_BE_STRIPPED", ""),
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
Object.assign(initializer, {
|
|
101
|
+
paramsAndIterator: Writers.object({
|
|
102
|
+
iterator: JSON.stringify(iterator),
|
|
103
|
+
params: "params",
|
|
104
|
+
}),
|
|
105
|
+
});
|
|
106
|
+
// Otherwise our interface will be inserted.
|
|
107
|
+
functionDeclaration.setBodyText("");
|
|
108
|
+
} else {
|
|
109
|
+
Object.assign(initializer, {paramsAndIterator: "null"});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (input != null) {
|
|
113
|
+
const property = classDeclaration.addProperty({
|
|
114
|
+
// isStatic: true,
|
|
115
|
+
name: input,
|
|
116
|
+
type: `_Types["${input}"]`,
|
|
117
|
+
initializer: JSON.stringify(values[input]),
|
|
118
|
+
});
|
|
119
|
+
functionDeclaration.addParameter({
|
|
120
|
+
name: "input",
|
|
121
|
+
type: `forms.FormOrFormSetValues<_Types["${input}"]>`,
|
|
122
|
+
});
|
|
123
|
+
functionDeclaration.setReturnType(
|
|
124
|
+
`Promise<rpcUtils.Result<_Types["${output}"], forms.FormOrFormSetErrors<_Types["${input}"]>, _Types["RPCPermission"]>>`,
|
|
125
|
+
);
|
|
126
|
+
Object.assign(initializer, {
|
|
127
|
+
input: Writers.object({
|
|
128
|
+
values: "input",
|
|
129
|
+
type: (writer: CodeBlockWriter) =>
|
|
130
|
+
writer.quote(type).write(" as const"),
|
|
131
|
+
}),
|
|
132
|
+
});
|
|
133
|
+
} else {
|
|
134
|
+
functionDeclaration.setReturnType(
|
|
135
|
+
`Promise<rpcUtils.Result<_Types["${output}"], null, _Types["RPCPermission"]>>`,
|
|
136
|
+
);
|
|
137
|
+
Object.assign(initializer, {input: "null"});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
functionDeclaration.addVariableStatement({
|
|
141
|
+
declarationKind: VariableDeclarationKind.Const,
|
|
142
|
+
declarations: [
|
|
143
|
+
{
|
|
144
|
+
name: "options",
|
|
145
|
+
initializer: Writers.object(initializer),
|
|
146
|
+
/*
|
|
147
|
+
x: 123,
|
|
148
|
+
y: (writer) => writer.quote("abc"),
|
|
149
|
+
z: Writers.object({
|
|
150
|
+
one: (writer) => writer.quote("1"),
|
|
151
|
+
}),
|
|
152
|
+
*/
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
});
|
|
156
|
+
functionDeclaration.setBodyText(
|
|
157
|
+
`${functionDeclaration.getBodyText()} return rpcUtils.rpcCall((this as any).requester, options)`,
|
|
158
|
+
);
|
|
159
|
+
/*
|
|
160
|
+
|
|
161
|
+
if (input != null) {
|
|
162
|
+
functionDeclaration.addParameter({
|
|
163
|
+
name: "input",
|
|
164
|
+
type: `forms.FormOrFormSetValues<_Types["${input}"]>`,
|
|
165
|
+
});
|
|
166
|
+
bodyText = bodyText.concat(`
|
|
167
|
+
const input = ${JSON.stringify({
|
|
168
|
+
type: "form",
|
|
169
|
+
})};
|
|
170
|
+
}
|
|
171
|
+
`);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
}
|
|
175
|
+
*/
|
|
176
|
+
|
|
177
|
+
/*
|
|
178
|
+
if (instance.length === 1) {
|
|
179
|
+
functionDeclaration.addParameter({name: "instance", type: `string | number`});
|
|
180
|
+
functionDeclaration.setBodyText(`return rpcUtils.rpcCall("${url}", input, "${type}", instance)`);
|
|
181
|
+
}
|
|
182
|
+
else if (instance.length >= 2) {
|
|
183
|
+
const instanceInterface = functionDeclaration.addInterface({name: "WILL_BE_STRIPPED"});
|
|
184
|
+
|
|
185
|
+
for (const instanceArg of instance) {
|
|
186
|
+
instanceInterface.addProperty({name: instanceArg, type: "string | number"});
|
|
187
|
+
}
|
|
188
|
+
functionDeclaration.addParameter({name: "instance", type: instanceInterface.getText().replace("interface WILL_BE_STRIPPED", "")});
|
|
189
|
+
functionDeclaration.setBodyText(`const iterator = ${JSON.stringify(instance)}; return rpcUtils.rpcCall("${url}", input, "${type}", {iterator, params: instance})`);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
functionDeclaration.setBodyText(`return rpcUtils.rpcCall("${url}", input, "${type}")`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
functionDeclaration.addParameter({name: "input", type: `forms.FormOrFormSetValues<_Types["${input}"]>`});
|
|
196
|
+
functionDeclaration.setReturnType(`Promise<rpcUtils.Result<_Types["${output}"], forms.FormOrFormSetErrors<_Types["${input}"]>>>`);
|
|
197
|
+
functionDeclaration.setIsAsync(true);
|
|
198
|
+
*/
|
|
199
|
+
}
|
|
200
|
+
rpcConstructor.setBodyText(rpcConstructorBody);
|
|
201
|
+
|
|
43
202
|
if (Object.keys(urls).length !== 0) {
|
|
44
203
|
sourceFile.addVariableStatement({
|
|
45
204
|
declarationKind: VariableDeclarationKind.Const,
|
|
@@ -116,14 +275,18 @@ if (Object.keys(urls).length !== 0) {
|
|
|
116
275
|
}
|
|
117
276
|
|
|
118
277
|
sourceFile.addStatements(`
|
|
278
|
+
export const rpc = new RPC(typeof window != "undefined" ? rpcUtils.defaultRequester : null as any);
|
|
119
279
|
import React from "react"
|
|
120
280
|
import createContext from "reactivated/dist/context";
|
|
121
281
|
import * as forms from "reactivated/dist/forms";
|
|
122
282
|
import * as generated from "reactivated/dist/generated";
|
|
283
|
+
import * as rpcUtils from "reactivated/dist/rpc";
|
|
123
284
|
|
|
124
285
|
// Note: this needs strict function types to behave correctly with excess properties etc.
|
|
125
286
|
export type Checker<P, U extends (React.FunctionComponent<P> | React.ComponentClass<P>)> = {};
|
|
126
287
|
|
|
288
|
+
export type Result<TSuccess, TInvalid> = rpcUtils.Result<TSuccess, TInvalid, _Types["RPCPermission"]>;
|
|
289
|
+
|
|
127
290
|
export const {Context, Provider, getServerData} = createContext<_Types["Context"]>();
|
|
128
291
|
|
|
129
292
|
export const getTemplate = ({template_name}: {template_name: string}) => {
|
|
@@ -144,6 +307,7 @@ export const {createRenderer, Iterator} = forms.bindWidgetType<_Types["globals"]
|
|
|
144
307
|
export type FieldHandler = forms.FieldHandler<_Types["globals"]["Widget"]>;
|
|
145
308
|
export type models = _Types["globals"]["models"];
|
|
146
309
|
|
|
310
|
+
export {FormHandler} from "reactivated/dist/forms";
|
|
147
311
|
export const {Form, FormSet, Widget, useForm, useFormSet, ManagementForm} = forms;
|
|
148
312
|
`);
|
|
149
313
|
|
|
@@ -152,9 +316,11 @@ compile(types, "this is unused").then((ts) => {
|
|
|
152
316
|
process.stdout.write("/* eslint-disable */\n");
|
|
153
317
|
process.stdout.write(ts);
|
|
154
318
|
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
319
|
+
if (!fs.existsSync("./reactivated-skip-template-check")) {
|
|
320
|
+
for (const name of Object.keys(templates)) {
|
|
321
|
+
const propsName = templates[name];
|
|
322
|
+
|
|
323
|
+
sourceFile.addStatements(`
|
|
158
324
|
|
|
159
325
|
import ${name}Implementation from "@client/templates/${name}"
|
|
160
326
|
export type ${name}Check = Checker<_Types["${propsName}"], typeof ${name}Implementation>;
|
|
@@ -165,6 +331,7 @@ export namespace templates {
|
|
|
165
331
|
|
|
166
332
|
|
|
167
333
|
`);
|
|
334
|
+
}
|
|
168
335
|
}
|
|
169
336
|
|
|
170
337
|
for (const name of Object.keys(interfaces)) {
|