@sealcode/sealgen 0.10.6 → 0.11.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/@types/add-jdd-component.d.ts +1 -0
- package/@types/forms/controls/array.d.ts +1 -1
- package/@types/forms/multiform.d.ts +1 -1
- package/@types/generate-components.d.ts +1 -0
- package/@types/templates/jdd-component.d.ts +1 -0
- package/@types/templates/templates.d.ts +2 -0
- package/lib/add-jdd-component.js +34 -0
- package/lib/add-route.js +4 -1
- package/lib/add-route.test.js +5 -2
- package/lib/build.js +15 -5
- package/lib/cli.js +4 -0
- package/lib/forms/multiform.test.js +2 -2
- package/lib/generate-components.js +63 -0
- package/lib/generate-routes.js +1 -1
- package/lib/templates/jdd-component.js +43 -0
- package/lib/templates/list.js +18 -20
- package/lib/templates/long-running-process.js +30 -26
- package/lib/templates/page.js +2 -2
- package/lib/templates/route-test.js +3 -2
- package/lib/templates/stateful-page.js +21 -17
- package/lib/templates/templates.js +2 -0
- package/lib/utils/import-path.js +1 -1
- package/package.json +5 -2
- package/src/add-jdd-component.ts +43 -0
- package/src/add-route.test.ts +6 -2
- package/src/add-route.ts +4 -1
- package/src/build.ts +15 -5
- package/src/cli.ts +4 -0
- package/src/forms/multiform.test.ts +2 -2
- package/src/generate-components.ts +46 -0
- package/src/generate-routes.ts +4 -1
- package/src/templates/jdd-component.ts +41 -0
- package/src/templates/list.ts +18 -20
- package/src/templates/long-running-process.ts +30 -26
- package/src/templates/page.ts +2 -2
- package/src/templates/route-test.ts +3 -2
- package/src/templates/stateful-page.ts +21 -17
- package/src/templates/templates.ts +2 -0
- package/src/utils/import-path.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function addJDDComponent(): Promise<void>;
|
|
@@ -25,7 +25,7 @@ export declare class StructuredArray<Subfields extends Record<string, Field>> ex
|
|
|
25
25
|
getActionURL(form_id?: string, action?: Record<string, unknown>): string;
|
|
26
26
|
getDefaultItemBody(): Promise<{}>;
|
|
27
27
|
makeSubfield(_field_name: string): FormField;
|
|
28
|
-
renderItemControl(ctx: Context, form_id: string, control: FormControl | UnboundControlStorage, item: FieldsetOutput<Subfields>, index: number): Promise<(string | number | import("stream").Readable | null) | (string | number | import("stream").Readable | null)[] | Promise<string | number | import("stream").Readable | null>[]
|
|
28
|
+
renderItemControl(ctx: Context, form_id: string, control: FormControl | UnboundControlStorage, item: FieldsetOutput<Subfields>, index: number): Promise<(string | number | import("stream").Readable | null) | (string | number | import("stream").Readable | null)[] | Promise<string | number | import("stream").Readable | null>[]>;
|
|
29
29
|
renderItem(ctx: Context, form_id: string, item: FieldsetOutput<Subfields>, index: number): Promise<import("stream").Readable>;
|
|
30
30
|
getItems(ctx: Context, raw_values: Record<string, FormDataValue>): Promise<FieldsetOutput<Subfields>[]>;
|
|
31
31
|
_render(ctx: Context, form_id: string, raw_values: Record<string, FormDataValue>): Promise<import("stream").Readable>;
|
|
@@ -17,7 +17,7 @@ export declare class Multiform extends MountableWithFields {
|
|
|
17
17
|
getSubformsToRender(ctx: Context): Array<readonly [string, Form<any, unknown>]>;
|
|
18
18
|
renderSubform(ctx: Context, sub_form_name: string, show_field_errors: boolean): Promise<FlatTemplatable>;
|
|
19
19
|
getSubformRawValues(ctx: Context, sub_form_name: string): Promise<Record<string, FormDataValue>>;
|
|
20
|
-
render(ctx: Context, messages: FormMessage[], prerenderedForms: Record<string,
|
|
20
|
+
render(ctx: Context, messages: FormMessage[], prerenderedForms: Record<string, import("tempstream/@types/stringify").Stringifiable | undefined> | undefined, show_field_errors: boolean): Promise<FlatTemplatable>;
|
|
21
21
|
makeBottomScript(): string;
|
|
22
22
|
mount(router: Router, path: string): void;
|
|
23
23
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateComponents(): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function jddComponentTemplate(component_name: string): string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { formTemplate } from "./form";
|
|
2
|
+
import { jddComponentTemplate } from "./jdd-component";
|
|
2
3
|
import { LongRunningProcessTemplate } from "./long-running-process";
|
|
3
4
|
import { multiformTemplate } from "./multiform";
|
|
4
5
|
import { pageTemplate } from "./page";
|
|
@@ -14,4 +15,5 @@ export declare const Templates: {
|
|
|
14
15
|
post: typeof postTemplate;
|
|
15
16
|
sreact: typeof statefulPageTemplate;
|
|
16
17
|
lpr: typeof LongRunningProcessTemplate;
|
|
18
|
+
jdd: typeof jddComponentTemplate;
|
|
17
19
|
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.addJDDComponent = void 0;
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const locreq_1 = __importDefault(require("locreq"));
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const question_1 = require("./utils/question");
|
|
11
|
+
const target_locreq = (0, locreq_1.default)(process.cwd());
|
|
12
|
+
const jdd_component_1 = require("./templates/jdd-component");
|
|
13
|
+
const generate_components_1 = require("./generate-components");
|
|
14
|
+
const js_convert_case_1 = require("js-convert-case");
|
|
15
|
+
async function addJDDComponent() {
|
|
16
|
+
const component_name = await (0, question_1.question)("What's the name of the component? > ", (s) => s.length > 3);
|
|
17
|
+
const file_path = target_locreq.resolve(`src/back/jdd-components/${(0, js_convert_case_1.toKebabCase)(component_name)}/${(0, js_convert_case_1.toKebabCase)(component_name)}.jdd.tsx`);
|
|
18
|
+
if ((0, fs_1.existsSync)(file_path)) {
|
|
19
|
+
// eslint-disable-next-line no-console
|
|
20
|
+
console.error(`ERROR: File ${file_path} already exists.`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
await fs_1.promises.mkdir((0, path_1.resolve)(file_path, "../"), { recursive: true });
|
|
24
|
+
await fs_1.promises.writeFile(file_path, (0, jdd_component_1.jddComponentTemplate)(component_name));
|
|
25
|
+
const css_file_path = target_locreq.resolve(`src/back/jdd-components/${(0, js_convert_case_1.toKebabCase)(component_name)}/${(0, js_convert_case_1.toKebabCase)(component_name)}.scss`);
|
|
26
|
+
await fs_1.promises.writeFile(css_file_path, `.${(0, js_convert_case_1.toKebabCase)(component_name)} {
|
|
27
|
+
}`);
|
|
28
|
+
// eslint-disable-next-line no-console
|
|
29
|
+
console.log(`Created ${file_path}`);
|
|
30
|
+
console.log(`Created ${css_file_path}`);
|
|
31
|
+
await (0, generate_components_1.generateComponents)();
|
|
32
|
+
}
|
|
33
|
+
exports.addJDDComponent = addJDDComponent;
|
|
34
|
+
//# sourceMappingURL=add-jdd-component.js.map
|
package/lib/add-route.js
CHANGED
|
@@ -45,7 +45,10 @@ async function addRoute(params, app_directory = process.cwd()) {
|
|
|
45
45
|
},
|
|
46
46
|
]);
|
|
47
47
|
const { action, url, mode } = response;
|
|
48
|
-
const
|
|
48
|
+
const extension = ["list", "lpr", "page", "sreact"].includes(mode)
|
|
49
|
+
? "tsx"
|
|
50
|
+
: "ts";
|
|
51
|
+
const file_path = target_locreq.resolve(`src/back/routes/${(0, escape_url_params_1.escape_url_params)(url)}.${mode}.${extension}`);
|
|
49
52
|
const test_file_path = target_locreq.resolve(`src/back/routes/${(0, escape_url_params_1.escape_url_params)(url)}.test.ts`);
|
|
50
53
|
const template = templates_1.Templates[mode];
|
|
51
54
|
if (!template) {
|
package/lib/add-route.test.js
CHANGED
|
@@ -9,7 +9,10 @@ const util_1 = require("util");
|
|
|
9
9
|
const axios_1 = __importDefault(require("axios"));
|
|
10
10
|
const wait_port_1 = __importDefault(require("wait-port"));
|
|
11
11
|
const get_port_1 = __importDefault(require("get-port"));
|
|
12
|
+
const locreq_1 = __importDefault(require("locreq"));
|
|
13
|
+
const target_locreq = (0, locreq_1.default)(__dirname);
|
|
12
14
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
15
|
+
const callSealgenBin = () => `node ${target_locreq.resolve("lib/cli.js")}`;
|
|
13
16
|
describe("add route test", () => {
|
|
14
17
|
let node_pid = 0;
|
|
15
18
|
const app_path = "/tmp/sealious-minimal";
|
|
@@ -30,11 +33,11 @@ describe("add route test", () => {
|
|
|
30
33
|
it("creates minimal sealious app", async function () {
|
|
31
34
|
this.timeout(250000);
|
|
32
35
|
console.log("\tcloning sealious-minimal...");
|
|
33
|
-
await execAsync(`git clone https://hub.sealcode.org/source/sealious-minimal.git ${app_path} && cd ${app_path} && git checkout
|
|
36
|
+
await execAsync(`git clone https://hub.sealcode.org/source/sealious-minimal.git ${app_path} && cd ${app_path} && git checkout d5abeb9514359dde4`);
|
|
34
37
|
console.log("\tinstalling dependencies and sealgen...");
|
|
35
38
|
await execAsync(`cd ${app_path} && npm ci && rm -rf node_modules/@sealcode/sealgen && ln -s $OLDPWD node_modules/@sealcode/sealgen`);
|
|
36
39
|
console.log("\trunning add-route and building app...");
|
|
37
|
-
await execAsync(`cd ${app_path} &&
|
|
40
|
+
await execAsync(`cd ${app_path} && ${callSealgenBin()} add-route --url=/sample --action=Sample --mode=page && ${callSealgenBin()} build`);
|
|
38
41
|
console.log("\tstarting the database...(if timeouts here, run 'docker pull mongo:4.4-bionic' to solve)");
|
|
39
42
|
const port = await (0, get_port_1.default)();
|
|
40
43
|
await execAsync(`docker run -p ${port}:27017 --name ${container_name} -d mongo:4.4-bionic`);
|
package/lib/build.js
CHANGED
|
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.buildProject = void 0;
|
|
30
30
|
const esbuild_1 = require("esbuild");
|
|
31
31
|
const fs_1 = require("fs");
|
|
32
|
+
const path_1 = require("path");
|
|
32
33
|
const esbuild_sass_plugin_1 = require("esbuild-sass-plugin");
|
|
33
34
|
const chokidar = __importStar(require("chokidar"));
|
|
34
35
|
const tiny_glob_1 = __importDefault(require("tiny-glob"));
|
|
@@ -37,20 +38,22 @@ const sleep_1 = require("./utils/sleep");
|
|
|
37
38
|
const generate_collections_1 = require("./generate-collections");
|
|
38
39
|
const generate_routes_1 = require("./generate-routes");
|
|
39
40
|
const generate_names = (function* generate_names() {
|
|
40
|
-
|
|
41
|
+
const base_name = "____unique_import_";
|
|
41
42
|
let count = 0;
|
|
42
43
|
while (true) {
|
|
43
|
-
yield base_name
|
|
44
|
+
yield `${base_name}${count}`;
|
|
44
45
|
count++;
|
|
45
46
|
}
|
|
46
47
|
})();
|
|
47
48
|
async function build_ts() {
|
|
48
49
|
await Promise.all([(0, generate_collections_1.generateCollections)(), (0, generate_routes_1.generateRoutes)()]);
|
|
49
|
-
const entryPoints = (await (0, tiny_glob_1.default)("./src/back/**/*.ts")).filter((path) => !path.includes(".#"));
|
|
50
|
+
const entryPoints = (await (0, tiny_glob_1.default)("./src/back/**/*.{ts,tsx}")).filter((path) => !path.includes(".#"));
|
|
50
51
|
try {
|
|
51
52
|
await (0, esbuild_1.build)({
|
|
52
53
|
entryPoints,
|
|
53
54
|
sourcemap: true,
|
|
55
|
+
bundle: false,
|
|
56
|
+
jsxFactory: "TempstreamJSX.createElement",
|
|
54
57
|
outdir: "./dist/back",
|
|
55
58
|
logLevel: "info",
|
|
56
59
|
platform: "node",
|
|
@@ -64,6 +67,7 @@ async function build_ts() {
|
|
|
64
67
|
const named_and_default_regex = /^import\s+((\S+),\s+)?({\s*[^}]+})\s+from\s+("[^"]+");\s*$/gm;
|
|
65
68
|
const old_content = await fs_1.promises.readFile(path, "utf-8");
|
|
66
69
|
const contents = old_content.replace(named_and_default_regex, (_, default_import_name, __, all_named, module_path) => {
|
|
70
|
+
/* eslint-disable */
|
|
67
71
|
const new_name = generate_names.next().value;
|
|
68
72
|
const result = `import * as ${new_name} from ${module_path}${default_import_name
|
|
69
73
|
? `; const ${default_import_name.replace(",", "")} = ${new_name}.default || ${new_name};`
|
|
@@ -83,8 +87,12 @@ async function build_ts() {
|
|
|
83
87
|
})
|
|
84
88
|
.join(" ");
|
|
85
89
|
return result;
|
|
90
|
+
/* eslint-enable */
|
|
86
91
|
});
|
|
87
|
-
return {
|
|
92
|
+
return {
|
|
93
|
+
contents,
|
|
94
|
+
loader: (0, path_1.extname)(path) === ".tsx" ? "tsx" : "ts",
|
|
95
|
+
};
|
|
88
96
|
});
|
|
89
97
|
},
|
|
90
98
|
},
|
|
@@ -92,6 +100,7 @@ async function build_ts() {
|
|
|
92
100
|
});
|
|
93
101
|
}
|
|
94
102
|
catch (e) {
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
95
104
|
console.error(e.message);
|
|
96
105
|
}
|
|
97
106
|
}
|
|
@@ -112,6 +121,7 @@ async function complex_build(watch) {
|
|
|
112
121
|
console.log(`Built main.scss [on ${path}]`);
|
|
113
122
|
}
|
|
114
123
|
catch (e) {
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
115
125
|
console.error(e.message);
|
|
116
126
|
await (0, sleep_1.sleep)(200);
|
|
117
127
|
scss_build
|
|
@@ -120,7 +130,7 @@ async function complex_build(watch) {
|
|
|
120
130
|
.catch((e) => console.error(e?.message));
|
|
121
131
|
}
|
|
122
132
|
}
|
|
123
|
-
if (path.endsWith(".ts") &&
|
|
133
|
+
if ((path.endsWith(".ts") || path.endsWith(".tsx")) &&
|
|
124
134
|
!path.endsWith("src/back/collections/collections.ts") &&
|
|
125
135
|
!path.endsWith("src/back/routes/routes.ts") &&
|
|
126
136
|
!path.endsWith("src/back/routes/urls.ts")) {
|
package/lib/cli.js
CHANGED
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const add_collection_1 = require("./add-collection");
|
|
5
|
+
const add_jdd_component_1 = require("./add-jdd-component");
|
|
5
6
|
const add_route_1 = require("./add-route");
|
|
6
7
|
const build_1 = require("./build");
|
|
7
8
|
const find_scss_includes_1 = require("./find-scss-includes");
|
|
8
9
|
const generate_collections_1 = require("./generate-collections");
|
|
10
|
+
const generate_components_1 = require("./generate-components");
|
|
9
11
|
const generate_routes_1 = require("./generate-routes");
|
|
10
12
|
const make_env_1 = require("./make-env");
|
|
11
13
|
const actions = {
|
|
12
14
|
"add-collection": add_collection_1.addCollection,
|
|
13
15
|
"add-route": add_route_1.addRoute,
|
|
14
16
|
"generate-collections": generate_collections_1.generateCollections,
|
|
17
|
+
"generate-components": generate_components_1.generateComponents,
|
|
15
18
|
"generate-routes": generate_routes_1.generateRoutes,
|
|
16
19
|
"generate-scss-includes": find_scss_includes_1.generateScssIncludes,
|
|
17
20
|
build: build_1.buildProject,
|
|
@@ -22,6 +25,7 @@ const actions = {
|
|
|
22
25
|
.join(", ")}`);
|
|
23
26
|
},
|
|
24
27
|
"make-env": make_env_1.makeEnv,
|
|
28
|
+
"add-component": add_jdd_component_1.addJDDComponent
|
|
25
29
|
};
|
|
26
30
|
void (async function () {
|
|
27
31
|
const action = process.argv.at(2);
|
|
@@ -107,8 +107,8 @@ async function general_form_validation_e2e_tests(js_enabled) {
|
|
|
107
107
|
await page.getByPlaceholder("password").click();
|
|
108
108
|
await page.getByPlaceholder("password").fill("test");
|
|
109
109
|
await page.locator("#multiform_test_form2_submit").click();
|
|
110
|
-
(0, utils_1.assertThrowsAsync)(async () => {
|
|
111
|
-
page.getByText("Incorrect input").click({ timeout: 500 });
|
|
110
|
+
await (0, utils_1.assertThrowsAsync)(async () => {
|
|
111
|
+
await page.getByText("Incorrect input").click({ timeout: 500 });
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
114
|
async function individual_field_validation_e2e_tests(javaScriptEnabled) {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.generateComponents = void 0;
|
|
30
|
+
const locreq_1 = __importDefault(require("locreq"));
|
|
31
|
+
const prettier = __importStar(require("prettier"));
|
|
32
|
+
const fs_1 = require("fs");
|
|
33
|
+
const prettier_1 = require("./utils/prettier");
|
|
34
|
+
const recursive_readdir_1 = __importDefault(require("recursive-readdir"));
|
|
35
|
+
const path_1 = __importDefault(require("path"));
|
|
36
|
+
const js_convert_case_1 = require("js-convert-case");
|
|
37
|
+
const target_locreq = (0, locreq_1.default)(process.cwd());
|
|
38
|
+
async function generateComponents() {
|
|
39
|
+
const components_dir = target_locreq.resolve("src/back/jdd-components");
|
|
40
|
+
const component_names = (await (0, recursive_readdir_1.default)(components_dir)).filter((c) => c.endsWith(".jdd.tsx"));
|
|
41
|
+
const component_data = component_names
|
|
42
|
+
.map((p) => "./" +
|
|
43
|
+
path_1.default.relative(components_dir, p).replace(/\.[tj]sx?$/, ".js"))
|
|
44
|
+
.map((relative_path) => {
|
|
45
|
+
const name = relative_path.match(/\/([^\/]+).jdd/)?.[1];
|
|
46
|
+
return { name, relative_path };
|
|
47
|
+
});
|
|
48
|
+
const content = `// DO NOT EDIT! This file is generated automaticaly with 'npm run generate-components'
|
|
49
|
+
import { Registry } from "@sealcode/jdd";
|
|
50
|
+
|
|
51
|
+
export const registry = new Registry();
|
|
52
|
+
${component_data
|
|
53
|
+
.map((c) => `
|
|
54
|
+
import { ${(0, js_convert_case_1.toPascalCase)(c.name)} } from "${c.relative_path}";
|
|
55
|
+
registry.add("${(0, js_convert_case_1.toKebabCase)(c.name)}", ${(0, js_convert_case_1.toPascalCase)(c.name)});`)
|
|
56
|
+
.join("\n")}`;
|
|
57
|
+
const target = "src/back/jdd-components/components.ts";
|
|
58
|
+
await fs_1.promises.writeFile(target_locreq.resolve(target), prettier.format(content, await (0, prettier_1.getPrettierConfig)()));
|
|
59
|
+
// eslint-disable-next-line no-console
|
|
60
|
+
console.log(`Successfuly generated new ${target} file`);
|
|
61
|
+
}
|
|
62
|
+
exports.generateComponents = generateComponents;
|
|
63
|
+
//# sourceMappingURL=generate-components.js.map
|
package/lib/generate-routes.js
CHANGED
|
@@ -66,7 +66,7 @@ function generateURL(actionName, url) {
|
|
|
66
66
|
}
|
|
67
67
|
async function generateRoutes() {
|
|
68
68
|
const files = await Promise.all((await (0, walk_1.walkDir)(target_locreq.resolve("src/back/routes")))
|
|
69
|
-
.filter((f) => Object.keys(templates_1.Templates).some((key) => f.endsWith(`.${key}.ts`)))
|
|
69
|
+
.filter((f) => Object.keys(templates_1.Templates).some((key) => f.endsWith(`.${key}.ts`) || f.endsWith(`.${key}.tsx`)))
|
|
70
70
|
.map(async (fullpath) => ({
|
|
71
71
|
fullpath,
|
|
72
72
|
actionName: await extractActionName(fullpath),
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.jddComponentTemplate = void 0;
|
|
4
|
+
const js_convert_case_1 = require("js-convert-case");
|
|
5
|
+
function jddComponentTemplate(component_name) {
|
|
6
|
+
return `import { FlatTemplatable, TempstreamJSX } from "tempstream";
|
|
7
|
+
import {
|
|
8
|
+
Component,
|
|
9
|
+
ComponentArguments,
|
|
10
|
+
ExtractStructuredComponentArgumentsValues,
|
|
11
|
+
JDDContext,
|
|
12
|
+
} from "@sealcode/jdd";
|
|
13
|
+
|
|
14
|
+
const component_arguments = {
|
|
15
|
+
title: new ComponentArguments.ShortText(),
|
|
16
|
+
content: new ComponentArguments.Markdown(),
|
|
17
|
+
} as const;
|
|
18
|
+
|
|
19
|
+
export class ${(0, js_convert_case_1.toPascalCase)(component_name)} extends Component<typeof component_arguments> {
|
|
20
|
+
getArguments() {
|
|
21
|
+
return component_arguments;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
toHTML(
|
|
25
|
+
{
|
|
26
|
+
title,
|
|
27
|
+
content,
|
|
28
|
+
}: ExtractStructuredComponentArgumentsValues<typeof component_arguments>,
|
|
29
|
+
{ render_markdown }: JDDContext
|
|
30
|
+
): FlatTemplatable {
|
|
31
|
+
return (
|
|
32
|
+
<div class="${(0, js_convert_case_1.toKebabCase)(component_name)}">
|
|
33
|
+
<h2>{title} • ${(0, js_convert_case_1.toPascalCase)(component_name)} </h2>
|
|
34
|
+
<div>{render_markdown(content)}</div>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
exports.jddComponentTemplate = jddComponentTemplate;
|
|
43
|
+
//# sourceMappingURL=jdd-component.js.map
|
package/lib/templates/list.js
CHANGED
|
@@ -29,8 +29,8 @@ const listTemplate = async (action_name, newfilefullpath) => {
|
|
|
29
29
|
]);
|
|
30
30
|
const rel = (0, import_path_1.curryImportPath)(newfilefullpath);
|
|
31
31
|
return `import { Context } from "koa";
|
|
32
|
-
import { CollectionItem
|
|
33
|
-
import { FlatTemplatable,
|
|
32
|
+
import { CollectionItem } from "sealious";
|
|
33
|
+
import { FlatTemplatable, TempstreamJSX } from "tempstream";
|
|
34
34
|
import { ${uppercase_collection} } from "${rel("src/back/collections/collections.js")}";
|
|
35
35
|
import html from "${rel("src/back/html.js")}";
|
|
36
36
|
import {
|
|
@@ -51,7 +51,7 @@ ${collection_fields
|
|
|
51
51
|
: `DefaultListFilters.fallback`} }`)
|
|
52
52
|
.join(",\n")}
|
|
53
53
|
] as {
|
|
54
|
-
field: keyof (typeof
|
|
54
|
+
field: keyof (typeof ${uppercase_collection})["fields"];
|
|
55
55
|
render?: ListFilterRender;
|
|
56
56
|
}[];
|
|
57
57
|
|
|
@@ -91,18 +91,18 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
|
|
|
91
91
|
const query_params = qs.parse(ctx.search.slice(1));
|
|
92
92
|
query_params.page = "1";
|
|
93
93
|
const filter_values = await this.getFilterValues(ctx);
|
|
94
|
-
return
|
|
95
|
-
|
|
94
|
+
return <form>
|
|
95
|
+
{Object.entries(query_params).map(([key, value]) => {
|
|
96
96
|
if (key == "filter") {
|
|
97
97
|
return "";
|
|
98
98
|
}
|
|
99
|
-
return
|
|
99
|
+
return <input
|
|
100
100
|
type="hidden"
|
|
101
101
|
name="\${key}"
|
|
102
102
|
value="\${value}"
|
|
103
|
-
|
|
103
|
+
/>;
|
|
104
104
|
})}
|
|
105
|
-
|
|
105
|
+
{filterFields.map(({ field, render }) => {
|
|
106
106
|
if (!render) {
|
|
107
107
|
render = DefaultListFilters.fallback;
|
|
108
108
|
}
|
|
@@ -113,31 +113,29 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
|
|
|
113
113
|
);
|
|
114
114
|
})}
|
|
115
115
|
<input type="submit" />
|
|
116
|
-
</form
|
|
116
|
+
</form>;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
async renderItem(_: Context, item: CollectionItem<typeof ${uppercase_collection}>) {
|
|
120
|
-
return
|
|
121
|
-
|
|
120
|
+
return <tr>
|
|
121
|
+
{displayFields.map(({ field, format }) => {
|
|
122
122
|
const value = item.get(field as any);
|
|
123
|
-
return
|
|
123
|
+
return <td>{format ? format(value) : value}</td>;
|
|
124
124
|
})}
|
|
125
|
-
</tr
|
|
125
|
+
</tr>;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
async render(ctx: Context) {
|
|
129
129
|
return html(
|
|
130
130
|
ctx,
|
|
131
131
|
"${action_name}",
|
|
132
|
-
|
|
133
|
-
<h2>${action_name}</h2>
|
|
132
|
+
<div>
|
|
133
|
+
<h2>${action_name} List</h2>
|
|
134
134
|
<table class="sealious-list">
|
|
135
|
-
|
|
136
|
-
<tbody>
|
|
137
|
-
\${super.render(ctx)}
|
|
138
|
-
</tbody>
|
|
135
|
+
{this.renderTableHead(ctx, displayFields)}
|
|
136
|
+
<tbody>{super.render(ctx)}</tbody>
|
|
139
137
|
</table>
|
|
140
|
-
</div
|
|
138
|
+
</div>
|
|
141
139
|
);
|
|
142
140
|
}
|
|
143
141
|
|
|
@@ -5,7 +5,7 @@ const import_path_1 = require("../utils/import-path");
|
|
|
5
5
|
async function LongRunningProcessTemplate(action_name, newfilefullpath) {
|
|
6
6
|
const rel = (0, import_path_1.curryImportPath)(newfilefullpath);
|
|
7
7
|
return `import { Context } from "koa";
|
|
8
|
-
import {
|
|
8
|
+
import { TempstreamJSX } from "tempstream";
|
|
9
9
|
import { Page } from "@sealcode/sealgen";
|
|
10
10
|
import html from "${rel("src/back/html.js")}";
|
|
11
11
|
import { LongRunningProcess } from "sealious";
|
|
@@ -23,34 +23,38 @@ export default new (class PatroniteAutoImportStatusPage extends Page {
|
|
|
23
23
|
async render(ctx: Context) {
|
|
24
24
|
const lpr_id = ctx.params.id;
|
|
25
25
|
const lpr_data = LongRunningProcess.getByID(ctx.$context, lpr_id);
|
|
26
|
+
const render_script = lpr_data.state !== "error" && lpr_data.state !== "finished";
|
|
27
|
+
const script = /* HTML */ \`<script>
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
document.location = document.location;
|
|
30
|
+
}, \${this.interval});
|
|
31
|
+
</script>\`;
|
|
32
|
+
|
|
26
33
|
return html(
|
|
27
34
|
ctx,
|
|
28
35
|
"PatroniteAutoImportStatus",
|
|
29
|
-
|
|
30
|
-
(lpr_data) =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
style="height:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
: ""}
|
|
52
|
-
\`
|
|
53
|
-
)}\`
|
|
36
|
+
<div>
|
|
37
|
+
{lpr_data.then((lpr_data) => {
|
|
38
|
+
return (
|
|
39
|
+
<div>
|
|
40
|
+
<div>status: {lpr_data.state}</div>
|
|
41
|
+
<div style="height: 20px; width: 100%">
|
|
42
|
+
<div
|
|
43
|
+
style="height: 100%; background-color: green; width: {Math.round(
|
|
44
|
+
lpr_data.progress * 100
|
|
45
|
+
)}%"
|
|
46
|
+
></div>
|
|
47
|
+
</div>
|
|
48
|
+
<div>
|
|
49
|
+
{lpr_data.events.map((e) => (
|
|
50
|
+
<div>{e.message}</div>
|
|
51
|
+
))}
|
|
52
|
+
</div>
|
|
53
|
+
{render_script ? { script } : ""}
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
})}
|
|
57
|
+
</div>
|
|
54
58
|
);
|
|
55
59
|
}
|
|
56
60
|
})();
|
package/lib/templates/page.js
CHANGED
|
@@ -5,7 +5,7 @@ const import_path_1 = require("../utils/import-path");
|
|
|
5
5
|
async function pageTemplate(action_name, newfilefullpath) {
|
|
6
6
|
const rel = (0, import_path_1.curryImportPath)(newfilefullpath);
|
|
7
7
|
return `import { Context } from "koa";
|
|
8
|
-
import {
|
|
8
|
+
import { TempstreamJSX } from "tempstream";
|
|
9
9
|
import { Page } from "@sealcode/sealgen";
|
|
10
10
|
import html from "${rel("src/back/html.js")}";
|
|
11
11
|
|
|
@@ -18,7 +18,7 @@ export default new (class ${action_name}Page extends Page {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
async render(ctx: Context) {
|
|
21
|
-
return html(ctx, "${action_name}",
|
|
21
|
+
return html(ctx, "${action_name}", <div></div>);
|
|
22
22
|
}
|
|
23
23
|
})();
|
|
24
24
|
`;
|
|
@@ -5,9 +5,10 @@ const import_path_1 = require("../utils/import-path");
|
|
|
5
5
|
function testTemplate(action_name, new_file_fullpath) {
|
|
6
6
|
const rel = (0, import_path_1.curryImportPath)(new_file_fullpath);
|
|
7
7
|
return `import { withProdApp } from "${rel("src/back/test_utils/with-prod-app.js")}";
|
|
8
|
-
import {
|
|
8
|
+
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "${rel("src/back/test_utils/webhint.js")}";
|
|
9
9
|
import { ${action_name}URL } from "${rel("src/back/routes/urls.js")}";
|
|
10
|
-
import { getBrowser } from "${rel("src/test_utils/browser-creator.js")}";
|
|
10
|
+
import { getBrowser } from "${rel("src/back/test_utils/browser-creator.js")}";
|
|
11
|
+
import { Browser, BrowserContext, Page } from "@playwright/test";
|
|
11
12
|
|
|
12
13
|
describe("${action_name} webhint", () => {
|
|
13
14
|
it(
|
|
@@ -4,14 +4,14 @@ exports.statefulPageTemplate = void 0;
|
|
|
4
4
|
const import_path_1 = require("../utils/import-path");
|
|
5
5
|
async function statefulPageTemplate(action_name, newfilefullpath) {
|
|
6
6
|
const rel = (0, import_path_1.curryImportPath)(newfilefullpath);
|
|
7
|
-
return `import {
|
|
8
|
-
import {
|
|
7
|
+
return `import { TempstreamJSX, Templatable } from "tempstream";
|
|
8
|
+
import { BaseContext } from "koa";
|
|
9
9
|
import { StatefulPage } from "@sealcode/sealgen";
|
|
10
10
|
import html from "${rel("src/back/html.js")}";
|
|
11
11
|
|
|
12
12
|
export const actionName = "${action_name}";
|
|
13
13
|
|
|
14
|
-
const actions =
|
|
14
|
+
const actions = {
|
|
15
15
|
add: (state: State, inputs: Record<string, string>) => {
|
|
16
16
|
console.log({ inputs });
|
|
17
17
|
return {
|
|
@@ -25,39 +25,43 @@ const actions = <const>{
|
|
|
25
25
|
elements: state.elements.filter((_, index) => index != index_to_remove),
|
|
26
26
|
};
|
|
27
27
|
},
|
|
28
|
-
};
|
|
28
|
+
} as const;
|
|
29
29
|
|
|
30
30
|
type State = {
|
|
31
31
|
elements: string[];
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
export default new (class ${action_name}Page extends StatefulPage<State, typeof actions> {
|
|
35
35
|
actions = actions;
|
|
36
36
|
|
|
37
37
|
getInitialState() {
|
|
38
38
|
return { elements: ["one", "two", "three"] };
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
wrapInLayout(ctx: BaseContext, content: Templatable): Templatable {
|
|
42
42
|
return html(ctx, "${action_name}", content);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
render(ctx: BaseContext, state: State, inputs: Record<string, string>) {
|
|
46
|
-
return
|
|
47
|
-
\${state.elements.map(
|
|
48
|
-
(e, index) => /* HTML */ \`<li>
|
|
49
|
-
\${e} \${this.makeActionButton(state, "remove", index)}
|
|
50
|
-
</li>\`
|
|
51
|
-
)}
|
|
52
|
-
</ul>
|
|
46
|
+
return (
|
|
53
47
|
<div>
|
|
54
|
-
<
|
|
48
|
+
<ul>
|
|
49
|
+
{state.elements.map((e, index) => (
|
|
50
|
+
<li>
|
|
51
|
+
{e} {this.makeActionButton(state, "remove", index)}
|
|
52
|
+
</li>
|
|
53
|
+
))}
|
|
54
|
+
</ul>
|
|
55
|
+
<div>
|
|
56
|
+
<input
|
|
55
57
|
name="element_to_add"
|
|
56
58
|
type="text"
|
|
57
|
-
value=
|
|
59
|
+
value={inputs.element_to_add || ""}
|
|
58
60
|
/>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
{this.makeActionButton(state, "add")}
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
61
65
|
}
|
|
62
66
|
})();
|
|
63
67
|
`;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Templates = void 0;
|
|
4
4
|
const form_1 = require("./form");
|
|
5
|
+
const jdd_component_1 = require("./jdd-component");
|
|
5
6
|
const list_1 = require("./list");
|
|
6
7
|
const long_running_process_1 = require("./long-running-process");
|
|
7
8
|
const multiform_1 = require("./multiform");
|
|
@@ -18,5 +19,6 @@ exports.Templates = {
|
|
|
18
19
|
post: post_1.postTemplate,
|
|
19
20
|
sreact: stateful_page_1.statefulPageTemplate,
|
|
20
21
|
lpr: long_running_process_1.LongRunningProcessTemplate,
|
|
22
|
+
jdd: jdd_component_1.jddComponentTemplate,
|
|
21
23
|
};
|
|
22
24
|
//# sourceMappingURL=templates.js.map
|
package/lib/utils/import-path.js
CHANGED
|
@@ -8,7 +8,7 @@ const path_1 = require("path");
|
|
|
8
8
|
const locreq_1 = __importDefault(require("locreq"));
|
|
9
9
|
const target_locreq = (0, locreq_1.default)(process.cwd());
|
|
10
10
|
function importPath(project_module_path, project_target_path) {
|
|
11
|
-
let result = (0, path_1.relative)((0, path_1.dirname)(target_locreq.resolve(project_module_path)), target_locreq.resolve(project_target_path).replace(/.
|
|
11
|
+
let result = (0, path_1.relative)((0, path_1.dirname)(target_locreq.resolve(project_module_path)), target_locreq.resolve(project_target_path).replace(/.tsx?$/, ".js"));
|
|
12
12
|
if (result[0] != ".") {
|
|
13
13
|
result = "./" + result;
|
|
14
14
|
}
|