@sealcode/sealgen 0.19.0 → 0.19.2
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/forms/fields/deep-reverse-single-reference-list.d.ts +1 -5
- package/@types/forms/fields/file.d.ts +1 -1
- package/@types/forms/fields/password.d.ts +1 -2
- package/@types/forms/fields/simple-form-field.d.ts +1 -1
- package/@types/forms/fields/single-reference.d.ts +1 -1
- package/@types/register-external.d.ts +2 -2
- package/@types/templates/form.d.ts +1 -3
- package/@types/templates/jdd-component.d.ts +1 -1
- package/@types/templates/page.d.ts +1 -1
- package/@types/templates/shared/shared-crud-form-fields.d.ts +1 -1
- package/@types/templates/templates.d.ts +1 -21
- package/eslint.config.mjs +56 -0
- package/lib/add-crud.js +1 -4
- package/lib/add-jdd-component.js +3 -3
- package/lib/add-route.js +2 -2
- package/lib/build.js +3 -3
- package/lib/builders/backend-ts-builder.js +0 -1
- package/lib/builders/colors-builder.js +11 -8
- package/lib/builders/fonts-builder.js +0 -1
- package/lib/builders/frontend-ts-builder.js +0 -1
- package/lib/cli.js +2 -2
- package/lib/components/tabs.js +36 -36
- package/lib/esbuild-plugins/rewrite-asset-imports.js +7 -10
- package/lib/forms/controls/array.js +5 -6
- package/lib/forms/controls/checkboxed-list-input.js +1 -2
- package/lib/forms/controls/checkboxed-list-input.test.js +6 -6
- package/lib/forms/controls/derived-frame.js +3 -3
- package/lib/forms/controls/dropdown.js +1 -2
- package/lib/forms/controls/file.test.js +1 -1
- package/lib/forms/controls/form-control.js +1 -1
- package/lib/forms/controls/image.test.js +2 -2
- package/lib/forms/controls/single-reference.test.js +1 -1
- package/lib/forms/controls/table.js +10 -15
- package/lib/forms/controls/textarea.js +1 -1
- package/lib/forms/fields/deep-reverse-single-reference-list.js +1 -1
- package/lib/forms/fields/field.test.js +3 -3
- package/lib/forms/fields/file.js +1 -1
- package/lib/forms/fields/file.test.js +1 -1
- package/lib/forms/fields/password.js +1 -1
- package/lib/forms/fields/simple-form-field.js +2 -1
- package/lib/forms/fields/single-reference.js +1 -1
- package/lib/forms/fields/structured-array.js +0 -2
- package/lib/forms/fields/table.js +1 -1
- package/lib/forms/form.js +0 -1
- package/lib/forms/form.test.js +2 -3
- package/lib/forms/multiform.js +6 -7
- package/lib/forms/multiform.test.js +2 -2
- package/lib/generate-collections.js +2 -3
- package/lib/generate-components.js +2 -3
- package/lib/generate-routes.js +3 -5
- package/lib/generate-routes.test.js +7 -16
- package/lib/generate-stimulus.js +4 -5
- package/lib/get-fonts.js +29 -27
- package/lib/make-env.js +1 -1
- package/lib/make-hidden-inputs.js +4 -4
- package/lib/mount.js +0 -1
- package/lib/notifier.js +3 -3
- package/lib/page/list.js +5 -7
- package/lib/page/mountable.js +0 -1
- package/lib/page/page.js +0 -1
- package/lib/register-external.js +4 -4
- package/lib/templates/form.js +1 -1
- package/lib/templates/jdd-component.js +1 -1
- package/lib/templates/jdd-editor.js +1 -1
- package/lib/templates/page.js +1 -1
- package/lib/templates/shared/collection-create-form.js +4 -5
- package/lib/templates/shared/collection-edit-form.js +4 -5
- package/lib/templates/shared/collection-list.js +2 -2
- package/lib/templates/shared/shared-crud-form-fields.js +3 -5
- package/lib/test_utils/exec_async.js +3 -3
- package/lib/test_utils/test-on-real-app.js +9 -11
- package/lib/utils/write-file.js +1 -1
- package/package.json +9 -8
- package/src/add-collection.ts +1 -3
- package/src/add-crud.ts +2 -7
- package/src/add-jdd-component.ts +4 -5
- package/src/add-route.ts +3 -6
- package/src/build.ts +3 -3
- package/src/builders/backend-ts-builder.ts +0 -1
- package/src/builders/builder.ts +4 -1
- package/src/builders/colors-builder.ts +11 -9
- package/src/builders/css-builder.ts +4 -1
- package/src/builders/fonts-builder.ts +0 -1
- package/src/builders/frontend-ts-builder.ts +0 -1
- package/src/cli.ts +2 -2
- package/src/components/tabs.ts +38 -37
- package/src/components/toggle-modal.ts +1 -1
- package/src/controllers/table-add-button.stimulus.ts +1 -1
- package/src/esbuild-plugins/rewrite-asset-imports.ts +7 -10
- package/src/forms/controls/array.ts +12 -16
- package/src/forms/controls/autocomplete.ts +1 -1
- package/src/forms/controls/big-radio-group.ts +2 -2
- package/src/forms/controls/checkbox-group.ts +1 -1
- package/src/forms/controls/checkboxed-list-input.test.ts +6 -6
- package/src/forms/controls/checkboxed-list-input.ts +18 -22
- package/src/forms/controls/derived-frame.ts +11 -10
- package/src/forms/controls/derived.ts +6 -5
- package/src/forms/controls/dropdown.ts +8 -11
- package/src/forms/controls/editable-collection-subset.ts +2 -1
- package/src/forms/controls/field-group.ts +1 -1
- package/src/forms/controls/file.test.ts +1 -1
- package/src/forms/controls/file.ts +4 -7
- package/src/forms/controls/form-control.ts +1 -1
- package/src/forms/controls/hidden-input.ts +1 -0
- package/src/forms/controls/html.ts +1 -0
- package/src/forms/controls/image.test.ts +2 -2
- package/src/forms/controls/image.ts +1 -1
- package/src/forms/controls/multiple-files.ts +5 -7
- package/src/forms/controls/multiple-images.ts +1 -1
- package/src/forms/controls/simple-input.ts +8 -4
- package/src/forms/controls/single-reference.test.ts +1 -1
- package/src/forms/controls/single-reference.ts +1 -1
- package/src/forms/controls/table.ts +16 -21
- package/src/forms/controls/textarea.ts +1 -1
- package/src/forms/controls/tickable.ts +0 -2
- package/src/forms/fields/boolean.ts +4 -1
- package/src/forms/fields/checkboxed-list.ts +1 -1
- package/src/forms/fields/collection-field.ts +5 -2
- package/src/forms/fields/color.ts +1 -1
- package/src/forms/fields/coordinates.ts +2 -2
- package/src/forms/fields/deep-reverse-single-reference-list.ts +2 -8
- package/src/forms/fields/deep-reverse-single-reference-table.ts +1 -1
- package/src/forms/fields/email.ts +1 -1
- package/src/forms/fields/enum-multiple-sealious.ts +1 -1
- package/src/forms/fields/existing-sealious-value.ts +1 -1
- package/src/forms/fields/field.test.ts +3 -3
- package/src/forms/fields/field.ts +6 -5
- package/src/forms/fields/file.test.ts +1 -1
- package/src/forms/fields/file.ts +2 -2
- package/src/forms/fields/float.ts +1 -1
- package/src/forms/fields/get-field-for-sealious.ts +97 -64
- package/src/forms/fields/int.ts +1 -1
- package/src/forms/fields/number.ts +2 -2
- package/src/forms/fields/password.ts +2 -6
- package/src/forms/fields/pick-from-list-sealious.ts +1 -1
- package/src/forms/fields/pick-from-list.ts +1 -1
- package/src/forms/fields/proxy-field.ts +1 -0
- package/src/forms/fields/simple-form-field.ts +13 -5
- package/src/forms/fields/single-reference.ts +2 -2
- package/src/forms/fields/structured-array.ts +2 -6
- package/src/forms/fields/table.ts +7 -15
- package/src/forms/fields/text.ts +1 -1
- package/src/forms/fields/url.ts +1 -1
- package/src/forms/form-types.ts +3 -4
- package/src/forms/form.test.ts +2 -3
- package/src/forms/form.ts +5 -7
- package/src/forms/multiform.test.ts +6 -6
- package/src/forms/multiform.ts +10 -10
- package/src/generate-collections.ts +2 -3
- package/src/generate-components.ts +2 -3
- package/src/generate-routes.test.ts +7 -16
- package/src/generate-routes.ts +6 -10
- package/src/generate-stimulus.ts +4 -6
- package/src/get-fonts.ts +32 -30
- package/src/make-env.ts +1 -1
- package/src/make-hidden-inputs.ts +8 -7
- package/src/mount.ts +2 -7
- package/src/notifier.ts +4 -6
- package/src/page/default-list-filters.ts +1 -0
- package/src/page/list.ts +18 -20
- package/src/page/mountable-with-fields.ts +3 -3
- package/src/page/mountable.ts +0 -1
- package/src/page/page.ts +2 -3
- package/src/page/props-parser.ts +1 -1
- package/src/page/sealious-list.ts +1 -1
- package/src/page/stateful-page.ts +6 -10
- package/src/register-external.ts +4 -4
- package/src/templates/form.ts +1 -2
- package/src/templates/jdd-component.ts +1 -1
- package/src/templates/jdd-editor.ts +2 -4
- package/src/templates/list.ts +0 -1
- package/src/templates/page.ts +1 -4
- package/src/templates/shared/collection-create-form.ts +5 -6
- package/src/templates/shared/collection-edit-form.ts +5 -6
- package/src/templates/shared/collection-list.ts +2 -2
- package/src/templates/shared/shared-crud-form-fields.ts +4 -9
- package/src/templates/templates.ts +5 -1
- package/src/test_utils/exec_async.ts +3 -4
- package/src/test_utils/test-on-real-app.ts +9 -11
- package/src/utils/browser-creator.js +0 -1
- package/src/utils/exec.ts +0 -1
- package/src/utils/input-wrapper.ts +1 -1
- package/src/utils/wrap-attributes.ts +1 -1
- package/src/utils/write-file.ts +1 -1
- package/.eslintrc.cjs +0 -44
|
@@ -105,7 +105,7 @@ ${field_import_string}
|
|
|
105
105
|
export const actionName = "${action_name}";
|
|
106
106
|
|
|
107
107
|
const filterFields:{
|
|
108
|
-
|
|
108
|
+
field: keyof (typeof ${uppercase_collection})["fields"];
|
|
109
109
|
render?: ListFilterRender;
|
|
110
110
|
prepareValue?: (filter_value: unknown) => unknown; // set this function to change what filter value is passed to Sealious
|
|
111
111
|
}[] = [
|
|
@@ -180,7 +180,7 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
|
|
|
180
180
|
ctx: Context,
|
|
181
181
|
fields: { field: string; label?: string }[]
|
|
182
182
|
): FlatTemplatable {
|
|
183
|
-
return tempstream/* HTML */ \`<thead>
|
|
183
|
+
return tempstream /* HTML */ \`<thead>
|
|
184
184
|
<tr>
|
|
185
185
|
\${fields.map(({ label, field }) => this.renderHeading(ctx, field, label))}
|
|
186
186
|
<th>Actions</th>
|
|
@@ -2,12 +2,10 @@ import { toPascalCase } from "js-convert-case";
|
|
|
2
2
|
import extract_fields_from_collection from "../../utils/extract-fields-from-collection.js";
|
|
3
3
|
import { formatWithPrettier } from "../../utils/prettier.js";
|
|
4
4
|
import { wrapAttribute } from "../../utils/wrap-attributes.js";
|
|
5
|
-
async function sharedCrudFormFields(collection_name
|
|
6
|
-
const collection_fields = await extract_fields_from_collection(
|
|
7
|
-
collection_name
|
|
8
|
-
);
|
|
5
|
+
async function sharedCrudFormFields(collection_name) {
|
|
6
|
+
const collection_fields = await extract_fields_from_collection(collection_name);
|
|
9
7
|
const uppercase_collection = toPascalCase(collection_name);
|
|
10
|
-
const result = `import { Controls, Fields } from "@sealcode/sealgen";
|
|
8
|
+
const result = `import { type Controls, Fields } from "@sealcode/sealgen";
|
|
11
9
|
import { ${uppercase_collection} } from "src/back/collections/collections.js";
|
|
12
10
|
${Array.from(
|
|
13
11
|
new Set(
|
|
@@ -2,12 +2,12 @@ import { exec } from "child_process";
|
|
|
2
2
|
const execAsync = (cmd) => {
|
|
3
3
|
return new Promise((resolve, reject) => {
|
|
4
4
|
const process = exec(cmd);
|
|
5
|
-
console.
|
|
5
|
+
console.info("EXECUTING", cmd);
|
|
6
6
|
process?.stdout?.on("data", (data) => {
|
|
7
|
-
console.
|
|
7
|
+
console.info(`stdout: ${data}`);
|
|
8
8
|
});
|
|
9
9
|
process?.stderr?.on("data", (data) => {
|
|
10
|
-
console.
|
|
10
|
+
console.info(`stdout: ${data}`);
|
|
11
11
|
});
|
|
12
12
|
process.on("exit", (code) => {
|
|
13
13
|
if (code == 0) {
|
|
@@ -22,15 +22,15 @@ class RealAppTest {
|
|
|
22
22
|
const timestamp = Date.now();
|
|
23
23
|
test_app.app_path = `/tmp/sealious-minimal-${timestamp}`;
|
|
24
24
|
test_app.container_name = `sealgen-test-mongo-${timestamp}`;
|
|
25
|
-
console.
|
|
25
|
+
console.info(" cloning sealious-minimal...");
|
|
26
26
|
await execAsync(
|
|
27
27
|
`git clone ${sealious_minimal_url} ${test_app.app_path} && cd ${test_app.app_path} && git checkout ${sealious_minimal_commit}`
|
|
28
28
|
);
|
|
29
|
-
console.
|
|
29
|
+
console.info(" installing dependencies and sealgen...");
|
|
30
30
|
await execAsync(
|
|
31
31
|
`cd ${test_app.app_path} && npm ci rm -rf node_modules/@sealcode/sealgen && ln -s $OLDPWD node_modules/@sealcode/sealgen && ${callSealgenBin()} make-env`
|
|
32
32
|
);
|
|
33
|
-
console.
|
|
33
|
+
console.info(
|
|
34
34
|
" starting the database...(if timeouts here, run 'docker pull mongo:4.4-bionic' to solve)"
|
|
35
35
|
);
|
|
36
36
|
await test_app.runSealgenCommand("build");
|
|
@@ -48,7 +48,7 @@ class RealAppTest {
|
|
|
48
48
|
SEALIOUS_PORT: this.app_port.toString()
|
|
49
49
|
};
|
|
50
50
|
const node_args = [`${this.app_path}/dist/back/index.js`];
|
|
51
|
-
console.
|
|
51
|
+
console.info(
|
|
52
52
|
"EXECUTING APP",
|
|
53
53
|
`${Object.entries(env).map(([key, value]) => `${key}=${value}`).join(" ")} node ${node_args.join(" ")}`
|
|
54
54
|
);
|
|
@@ -57,9 +57,9 @@ class RealAppTest {
|
|
|
57
57
|
});
|
|
58
58
|
app_start.stdout.on(
|
|
59
59
|
"data",
|
|
60
|
-
(data) => console.
|
|
60
|
+
(data) => console.info("APP OUTPUT:", data.toString())
|
|
61
61
|
);
|
|
62
|
-
app_start.stderr.on("data", (data) => console.
|
|
62
|
+
app_start.stderr.on("data", (data) => console.info(data.toString()));
|
|
63
63
|
app_start.on("exit", (code) => {
|
|
64
64
|
this.emitter.emit("exit", code);
|
|
65
65
|
this.emitter.emit("process_error");
|
|
@@ -73,7 +73,7 @@ class RealAppTest {
|
|
|
73
73
|
output: "silent",
|
|
74
74
|
timeout: 6e3
|
|
75
75
|
});
|
|
76
|
-
console.
|
|
76
|
+
console.info(
|
|
77
77
|
chalk.yellow(
|
|
78
78
|
`App is listening on http://localhost:${this.app_port}`
|
|
79
79
|
)
|
|
@@ -83,7 +83,7 @@ class RealAppTest {
|
|
|
83
83
|
try {
|
|
84
84
|
if (this.node_pid != 0)
|
|
85
85
|
await execAsync(`kill -9 ${this.node_pid}`);
|
|
86
|
-
} catch (
|
|
86
|
+
} catch (_error) {
|
|
87
87
|
throw new Error(
|
|
88
88
|
"node process exited unexpectedly, please inspect the output"
|
|
89
89
|
);
|
|
@@ -147,13 +147,11 @@ class RealAppTest {
|
|
|
147
147
|
);
|
|
148
148
|
const status = ret.status;
|
|
149
149
|
const response = await ret.text();
|
|
150
|
-
console.debug("request done!");
|
|
151
|
-
console.debug({ response });
|
|
152
150
|
return { status, response };
|
|
153
151
|
});
|
|
154
152
|
}
|
|
155
153
|
async addFile(target_path, content) {
|
|
156
|
-
console.
|
|
154
|
+
console.info(
|
|
157
155
|
chalk.yellow("Inserting file at path"),
|
|
158
156
|
chalk.green(target_path),
|
|
159
157
|
"with content\n",
|
package/lib/utils/write-file.js
CHANGED
|
@@ -3,7 +3,7 @@ import { resolve } from "path";
|
|
|
3
3
|
async function writeFile(path, content) {
|
|
4
4
|
await fs.mkdir(resolve(path, "../"), { recursive: true });
|
|
5
5
|
await fs.writeFile(path, content);
|
|
6
|
-
console.
|
|
6
|
+
console.info(`${path} created`);
|
|
7
7
|
}
|
|
8
8
|
export {
|
|
9
9
|
writeFile
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealcode/sealgen",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.2",
|
|
4
4
|
"description": "Module to automate adding routes and collections to a sealious application",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"@types/wcag-contrast": "^3.0.3",
|
|
40
40
|
"@types/ws": "^8.5.10",
|
|
41
41
|
"@types/yargs": "^17.0.32",
|
|
42
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
43
|
-
"@typescript-eslint/parser": "^
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "^8.44.0",
|
|
43
|
+
"@typescript-eslint/parser": "^8.44.0",
|
|
44
44
|
"axios": "^1.6.7",
|
|
45
45
|
"chalk": "^5.3.0",
|
|
46
|
-
"eslint": "^
|
|
47
|
-
"eslint-config-prettier": "^8.
|
|
48
|
-
"eslint-plugin-prettier": "^
|
|
46
|
+
"eslint": "^9.36.0",
|
|
47
|
+
"eslint-config-prettier": "^8.10.2",
|
|
48
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
49
49
|
"eslint-plugin-with-tsc-error": "^0.0.7",
|
|
50
50
|
"get-port": "^5.1.1",
|
|
51
51
|
"koa-body": "^5.0.0",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"source-map-support": "^0.5.21",
|
|
57
57
|
"ts-node": "^10.9.1",
|
|
58
58
|
"typescript": "5.9",
|
|
59
|
+
"typescript-eslint": "^8.44.0",
|
|
59
60
|
"wait-port": "^1.0.4"
|
|
60
61
|
},
|
|
61
62
|
"types": "./@types/index.d.ts",
|
|
@@ -77,7 +78,7 @@
|
|
|
77
78
|
"locreq": "^3.0.0",
|
|
78
79
|
"md5": "^2.3.0",
|
|
79
80
|
"merge": "^2.1.1",
|
|
80
|
-
"prettier": "^
|
|
81
|
+
"prettier": "^3.6.2",
|
|
81
82
|
"prompts": "^2.4.2",
|
|
82
83
|
"recursive-readdir": "^2.2.3",
|
|
83
84
|
"tempfile": "^5.0.0",
|
|
@@ -90,7 +91,7 @@
|
|
|
90
91
|
"peerDependencies": {
|
|
91
92
|
"koa": "^2.13.0",
|
|
92
93
|
"koa-responsive-image-router": "^0.2.24",
|
|
93
|
-
"sealious": "^0.21",
|
|
94
|
+
"sealious": "^0.21.20",
|
|
94
95
|
"stimulus": "^3.2.2"
|
|
95
96
|
}
|
|
96
97
|
}
|
package/src/add-collection.ts
CHANGED
|
@@ -25,8 +25,7 @@ export async function addCollection(
|
|
|
25
25
|
},
|
|
26
26
|
]);
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
const collection_name: string = response.collection_name;
|
|
28
|
+
const collection_name: string = response.collection_name as string;
|
|
30
29
|
|
|
31
30
|
if (!collection_name) {
|
|
32
31
|
throw new Error("Empty collection name, please try again");
|
|
@@ -36,7 +35,6 @@ export async function addCollection(
|
|
|
36
35
|
);
|
|
37
36
|
|
|
38
37
|
if (existsSync(file_path)) {
|
|
39
|
-
// eslint-disable-next-line no-console
|
|
40
38
|
console.error(`ERROR: File ${file_path} already exists.`);
|
|
41
39
|
return;
|
|
42
40
|
}
|
package/src/add-crud.ts
CHANGED
|
@@ -24,9 +24,7 @@ export async function addCRUD(
|
|
|
24
24
|
name: "collection",
|
|
25
25
|
message:
|
|
26
26
|
"Which sealious collection do you like to add CRUD forms for?",
|
|
27
|
-
choices: (
|
|
28
|
-
await listCollections()
|
|
29
|
-
).map((collection) => ({
|
|
27
|
+
choices: (await listCollections()).map((collection) => ({
|
|
30
28
|
title: collection,
|
|
31
29
|
value: collection,
|
|
32
30
|
})),
|
|
@@ -90,10 +88,7 @@ export async function addCRUD(
|
|
|
90
88
|
const fields_path = target_locreq.resolve(
|
|
91
89
|
`src/back/routes/${escape_url_params(url)}/shared.ts`
|
|
92
90
|
);
|
|
93
|
-
const fields_content = await sharedCrudFormFields(
|
|
94
|
-
collection_name,
|
|
95
|
-
fields_path
|
|
96
|
-
);
|
|
91
|
+
const fields_content = await sharedCrudFormFields(collection_name);
|
|
97
92
|
await writeFile(fields_path, fields_content);
|
|
98
93
|
|
|
99
94
|
/* create the create endpoint */
|
package/src/add-jdd-component.ts
CHANGED
|
@@ -19,12 +19,11 @@ export async function addJDDComponent(): Promise<void> {
|
|
|
19
19
|
);
|
|
20
20
|
|
|
21
21
|
if (existsSync(file_path)) {
|
|
22
|
-
// eslint-disable-next-line no-console
|
|
23
22
|
console.error(`ERROR: File ${file_path} already exists.`);
|
|
24
23
|
return;
|
|
25
24
|
}
|
|
26
25
|
await fs.mkdir(resolve(file_path, "../"), { recursive: true });
|
|
27
|
-
await fs.writeFile(file_path, jddComponentTemplate(component_name));
|
|
26
|
+
await fs.writeFile(file_path, await jddComponentTemplate(component_name));
|
|
28
27
|
|
|
29
28
|
const css_file_path = target_locreq.resolve(
|
|
30
29
|
`src/back/jdd-components/${toKebabCase(component_name)}/${toKebabCase(
|
|
@@ -36,8 +35,8 @@ export async function addJDDComponent(): Promise<void> {
|
|
|
36
35
|
`.${toKebabCase(component_name)} {
|
|
37
36
|
}`
|
|
38
37
|
);
|
|
39
|
-
|
|
40
|
-
console.
|
|
41
|
-
console.
|
|
38
|
+
|
|
39
|
+
console.info(`Created ${file_path}`);
|
|
40
|
+
console.info(`Created ${css_file_path}`);
|
|
42
41
|
await generateComponents();
|
|
43
42
|
}
|
package/src/add-route.ts
CHANGED
|
@@ -67,22 +67,19 @@ export async function addRoute(
|
|
|
67
67
|
const test_file_path = target_locreq.resolve(
|
|
68
68
|
`src/back/routes/${base_file_name}.test.ts`
|
|
69
69
|
);
|
|
70
|
-
const template = Templates[mode
|
|
70
|
+
const template = Templates[mode];
|
|
71
71
|
|
|
72
72
|
if (!template) {
|
|
73
73
|
throw new Error(`Could not get template ${mode}`);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
if (existsSync(file_path)) {
|
|
77
|
-
// eslint-disable-next-line no-console
|
|
78
77
|
console.error(`ERROR: File ${file_path} already exists.`);
|
|
79
78
|
return;
|
|
80
79
|
}
|
|
81
80
|
await fs.mkdir(resolve(file_path, "../"), { recursive: true });
|
|
82
81
|
await fs.writeFile(file_path, await template(action, file_path));
|
|
83
|
-
|
|
84
|
-
console.
|
|
85
|
-
// eslint-disable-next-line no-console
|
|
86
|
-
console.log(`${test_file_path} created`);
|
|
82
|
+
console.info(`${file_path} created`);
|
|
83
|
+
console.info(`${test_file_path} created`);
|
|
87
84
|
await generateRoutes();
|
|
88
85
|
}
|
package/src/build.ts
CHANGED
|
@@ -64,7 +64,7 @@ async function build(watch: boolean): Promise<void> {
|
|
|
64
64
|
copy_to_public.map(async ({ from, to }) => {
|
|
65
65
|
try {
|
|
66
66
|
await fs.stat(resolve(project_dir, "public", to));
|
|
67
|
-
} catch (
|
|
67
|
+
} catch (_e) {
|
|
68
68
|
await fs.mkdir(resolve(project_dir, "public", to, "../"), {
|
|
69
69
|
recursive: true,
|
|
70
70
|
});
|
|
@@ -101,7 +101,7 @@ async function build(watch: boolean): Promise<void> {
|
|
|
101
101
|
const notifier = make_notifier(port, 8080); // TODO: parse the app config to get the actual port
|
|
102
102
|
await write_notifier_config(watch, port);
|
|
103
103
|
watcher.on("all", (_, file_path) => {
|
|
104
|
-
console.
|
|
104
|
+
console.info("Detected a change!", file_path);
|
|
105
105
|
builders.forEach((builder) => {
|
|
106
106
|
const owns_a_file = builder.ownsFile(file_path);
|
|
107
107
|
if (owns_a_file) {
|
|
@@ -125,7 +125,7 @@ export async function buildProject({
|
|
|
125
125
|
try {
|
|
126
126
|
await build(watch);
|
|
127
127
|
} catch (e) {
|
|
128
|
-
console.
|
|
128
|
+
console.error("CAUGHT!");
|
|
129
129
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
130
130
|
console.error(e.message);
|
|
131
131
|
if (!watch) {
|
package/src/builders/builder.ts
CHANGED
|
@@ -4,7 +4,10 @@ export abstract class Builder {
|
|
|
4
4
|
abstract _build(): Promise<void>;
|
|
5
5
|
abstract dispose(): Promise<void>;
|
|
6
6
|
|
|
7
|
-
constructor(
|
|
7
|
+
constructor(
|
|
8
|
+
public project_dir: string,
|
|
9
|
+
public style_dirs: string[]
|
|
10
|
+
) {}
|
|
8
11
|
|
|
9
12
|
public ongoing_build: Promise<void> | null = null;
|
|
10
13
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
1
|
import { build } from "esbuild";
|
|
3
2
|
import tempfile from "tempfile";
|
|
4
3
|
import { promises as fs } from "fs";
|
|
@@ -26,7 +25,6 @@ export class ColorsBuilder extends Builder {
|
|
|
26
25
|
return file_path == COLORS_TS_PATH;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
30
28
|
async dispose(): Promise<void> {}
|
|
31
29
|
|
|
32
30
|
async _build() {
|
|
@@ -242,8 +240,12 @@ export class ColorsBuilder extends Builder {
|
|
|
242
240
|
|
|
243
241
|
.hex {
|
|
244
242
|
padding: 8px;
|
|
245
|
-
font-family:
|
|
246
|
-
|
|
243
|
+
font-family:
|
|
244
|
+
Menlo,
|
|
245
|
+
Consolas,
|
|
246
|
+
Monaco,
|
|
247
|
+
Liberation Mono,
|
|
248
|
+
Lucida Console,
|
|
247
249
|
monospace;
|
|
248
250
|
opacity: 0.5;
|
|
249
251
|
visibility: hidden;
|
|
@@ -433,16 +435,16 @@ export class ColorsBuilder extends Builder {
|
|
|
433
435
|
)
|
|
434
436
|
? \`var(--color-\${box.getAttribute(
|
|
435
437
|
"data-color-group-name"
|
|
436
|
-
|
|
438
|
+
)}-\${box.getAttribute(
|
|
437
439
|
"data-color-name"
|
|
438
|
-
|
|
440
|
+
)})\`
|
|
439
441
|
: \`var(--color-\${box.getAttribute(
|
|
440
442
|
"data-color-group-name"
|
|
441
|
-
|
|
443
|
+
)}-\${box.getAttribute(
|
|
442
444
|
"data-color-name"
|
|
443
|
-
|
|
445
|
+
)}-\${box.getAttribute(
|
|
444
446
|
"data-color-shade-number"
|
|
445
|
-
|
|
447
|
+
)})\`;
|
|
446
448
|
navigator.clipboard.writeText(css_var);
|
|
447
449
|
pop_toast();
|
|
448
450
|
}
|
|
@@ -7,7 +7,10 @@ import { Builder } from "./builder.js";
|
|
|
7
7
|
|
|
8
8
|
export class CSSClump {
|
|
9
9
|
public files: string[] = [];
|
|
10
|
-
constructor(
|
|
10
|
+
constructor(
|
|
11
|
+
public project_dir: string,
|
|
12
|
+
public name: string
|
|
13
|
+
) {}
|
|
11
14
|
|
|
12
15
|
addFile(full_path: string) {
|
|
13
16
|
this.files.push(full_path);
|
package/src/cli.ts
CHANGED
|
@@ -28,8 +28,8 @@ const actions: Record<
|
|
|
28
28
|
"generate-routes": generateRoutes,
|
|
29
29
|
build: buildProject,
|
|
30
30
|
default: async function () {
|
|
31
|
-
console.
|
|
32
|
-
console.
|
|
31
|
+
console.info("Usage: `npx sealgen <action>`");
|
|
32
|
+
console.info(
|
|
33
33
|
`Available actions: ${Object.keys(actions)
|
|
34
34
|
.filter((e) => e != "default")
|
|
35
35
|
.join(", ")}`
|
package/src/components/tabs.ts
CHANGED
|
@@ -4,52 +4,53 @@ function name_to_id(str: string) {
|
|
|
4
4
|
return str.replace(/\W/g, "-");
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
const style = (hide_tabs_width: number) =>
|
|
8
|
-
|
|
9
|
-
height: 45px;
|
|
10
|
-
line-height: 45px;
|
|
11
|
-
padding: 0 45px;
|
|
12
|
-
display: block;
|
|
13
|
-
float: left;
|
|
14
|
-
box-sizing: border-box;
|
|
15
|
-
border-bottom: 3px solid transparent;
|
|
16
|
-
cursor: pointer;
|
|
17
|
-
font-size: 18px;
|
|
18
|
-
-webkit-user-select: none;
|
|
19
|
-
user-select: none;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
@media screen and (max-width: ${hide_tabs_width}px) {
|
|
7
|
+
const style = (hide_tabs_width: number) =>
|
|
8
|
+
/* HTML */ `<style>
|
|
23
9
|
.tab-label {
|
|
24
|
-
|
|
10
|
+
height: 45px;
|
|
11
|
+
line-height: 45px;
|
|
12
|
+
padding: 0 45px;
|
|
13
|
+
display: block;
|
|
14
|
+
float: left;
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
border-bottom: 3px solid transparent;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
font-size: 18px;
|
|
19
|
+
-webkit-user-select: none;
|
|
20
|
+
user-select: none;
|
|
25
21
|
}
|
|
26
|
-
}
|
|
27
22
|
|
|
28
|
-
.tab-label--mobile {
|
|
29
|
-
line-height: unset;
|
|
30
|
-
padding-top: 30px;
|
|
31
|
-
padding-left: 0;
|
|
32
|
-
pointer-events: none;
|
|
33
|
-
padding-bottom: 30px;
|
|
34
|
-
color: $font-graphite;
|
|
35
|
-
border-bottom: 2px solid $font-primary;
|
|
36
|
-
display: none;
|
|
37
23
|
@media screen and (max-width: ${hide_tabs_width}px) {
|
|
38
|
-
|
|
24
|
+
.tab-label {
|
|
25
|
+
display: none;
|
|
26
|
+
}
|
|
39
27
|
}
|
|
40
|
-
}
|
|
41
28
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
29
|
+
.tab-label--mobile {
|
|
30
|
+
line-height: unset;
|
|
31
|
+
padding-top: 30px;
|
|
32
|
+
padding-left: 0;
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
padding-bottom: 30px;
|
|
35
|
+
color: $font-graphite;
|
|
36
|
+
border-bottom: 2px solid $font-primary;
|
|
37
|
+
display: none;
|
|
38
|
+
@media screen and (max-width: ${hide_tabs_width}px) {
|
|
39
|
+
display: block;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
46
42
|
|
|
47
|
-
@media screen and (max-width: ${hide_tabs_width}px) {
|
|
48
43
|
.tab-content {
|
|
49
|
-
|
|
44
|
+
padding-top: 30px;
|
|
45
|
+
clear: both;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@media screen and (max-width: ${hide_tabs_width}px) {
|
|
49
|
+
.tab-content {
|
|
50
|
+
display: block !important;
|
|
51
|
+
}
|
|
50
52
|
}
|
|
51
|
-
|
|
52
|
-
</style>`;
|
|
53
|
+
</style>`;
|
|
53
54
|
|
|
54
55
|
export function tabs(
|
|
55
56
|
tabs: Record<string, FlatTemplatable>,
|
|
@@ -10,7 +10,7 @@ export function toggleModal(options: {
|
|
|
10
10
|
}) {
|
|
11
11
|
const { contentWrapped, contentUnwrapped, name } = options;
|
|
12
12
|
const id = makeSlug(name);
|
|
13
|
-
return tempstream/* HTML */ `<style>
|
|
13
|
+
return tempstream /* HTML */ `<style>
|
|
14
14
|
.toggle-modal__wrapped {
|
|
15
15
|
display: none;
|
|
16
16
|
}
|
|
@@ -28,7 +28,7 @@ export default class extends Controller {
|
|
|
28
28
|
placeholder,
|
|
29
29
|
String(tbody.querySelectorAll("tr").length)
|
|
30
30
|
);
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
32
32
|
tbody.appendChild((template.cloneNode(true) as any).content);
|
|
33
33
|
template.innerHTML = orig_template;
|
|
34
34
|
}
|
|
@@ -22,16 +22,13 @@ export const rewrite_asset_imports_plugin = (project_dir: string) => ({
|
|
|
22
22
|
`^import ([^ ]+, )?(\\w+|{[^}]+}) from "([^"]+)";`,
|
|
23
23
|
"gm"
|
|
24
24
|
);
|
|
25
|
-
contents = contents.replaceAll(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return replaced;
|
|
33
|
-
}
|
|
34
|
-
);
|
|
25
|
+
contents = contents.replaceAll(regex_import, (line) => {
|
|
26
|
+
const replaced = line.replace(
|
|
27
|
+
`"src/`,
|
|
28
|
+
`"` + resolve(project_dir, "./dist") + "/"
|
|
29
|
+
);
|
|
30
|
+
return replaced;
|
|
31
|
+
});
|
|
35
32
|
|
|
36
33
|
return {
|
|
37
34
|
contents,
|
|
@@ -16,11 +16,11 @@ import { FormFieldControl } from "./form-field-control.js";
|
|
|
16
16
|
export type UnboundControlStorage<
|
|
17
17
|
F extends { new (...args: any): FormFieldControl } = {
|
|
18
18
|
new (...args: any): FormFieldControl;
|
|
19
|
-
}
|
|
19
|
+
},
|
|
20
20
|
> = [F, string, ConstructorParameters<F>];
|
|
21
21
|
|
|
22
22
|
export function UnboundControl<
|
|
23
|
-
F extends { new (...args: any): FormFieldControl }
|
|
23
|
+
F extends { new (...args: any): FormFieldControl },
|
|
24
24
|
>(
|
|
25
25
|
controlClass: F,
|
|
26
26
|
arbitrary_field_name: string,
|
|
@@ -30,7 +30,7 @@ export function UnboundControl<
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export class StructuredArray<
|
|
33
|
-
Subfields extends Record<string, Field<any
|
|
33
|
+
Subfields extends Record<string, Field<any>>,
|
|
34
34
|
> extends FormFieldControl {
|
|
35
35
|
constructor(
|
|
36
36
|
public field: StructuredArrayField<Subfields>,
|
|
@@ -77,7 +77,6 @@ export class StructuredArray<
|
|
|
77
77
|
validate: false,
|
|
78
78
|
} as FormControlContext;
|
|
79
79
|
if (Array.isArray(control)) {
|
|
80
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
81
80
|
const [constructor, field_name, params] = control;
|
|
82
81
|
const field = this.makeSubfield(field_name);
|
|
83
82
|
if (!field) {
|
|
@@ -89,15 +88,13 @@ export class StructuredArray<
|
|
|
89
88
|
field.setName(`${this.field.name}[data][${index}][${field_name}]`);
|
|
90
89
|
const hidden_shadow = new Derived(
|
|
91
90
|
[field],
|
|
92
|
-
async (
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
form="${inner_form_id}"
|
|
100
|
-
/>`,
|
|
91
|
+
async (values, { inner_form_id, field_name }) =>
|
|
92
|
+
/* HTML */ `<input
|
|
93
|
+
name="${field_name}"
|
|
94
|
+
type="hidden"
|
|
95
|
+
value="${values[field_name] || ""}"
|
|
96
|
+
form="${inner_form_id}"
|
|
97
|
+
/>`,
|
|
101
98
|
async () => ({
|
|
102
99
|
inner_form_id: this.getInnerFormID(),
|
|
103
100
|
field_name: field.name,
|
|
@@ -134,7 +131,7 @@ export class StructuredArray<
|
|
|
134
131
|
item: FieldsetOutput<Subfields>,
|
|
135
132
|
index: number
|
|
136
133
|
) {
|
|
137
|
-
return tempstream/* HTML */ `<div>
|
|
134
|
+
return tempstream /* HTML */ `<div>
|
|
138
135
|
${this.item_controls.map((control) =>
|
|
139
136
|
this.renderItemControl(ctx, form_id, control, item, index)
|
|
140
137
|
)}
|
|
@@ -161,7 +158,7 @@ export class StructuredArray<
|
|
|
161
158
|
) {
|
|
162
159
|
const items = await this.getItems(ctx, raw_values);
|
|
163
160
|
|
|
164
|
-
return tempstream/* HTML */ `<turbo-frame id="${this.getFrameID()}">
|
|
161
|
+
return tempstream /* HTML */ `<turbo-frame id="${this.getFrameID()}">
|
|
165
162
|
Reverse Single Reference
|
|
166
163
|
${items.map((item, index) =>
|
|
167
164
|
this.renderItem(ctx, form_id, item, index)
|
|
@@ -223,7 +220,6 @@ export class StructuredArray<
|
|
|
223
220
|
data: field_data.data || [],
|
|
224
221
|
});
|
|
225
222
|
await item.save(ctx.$context);
|
|
226
|
-
console.log(await item.getDecodedBody(ctx.$context, {}));
|
|
227
223
|
ctx.body = this._render(
|
|
228
224
|
ctx,
|
|
229
225
|
form_id,
|
|
@@ -24,7 +24,7 @@ export class Autocomplete extends SimpleInput {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async postInput(ctx: Context) {
|
|
27
|
-
return tempstream/* HTML */ `<datalist id="${this.getListID()}">
|
|
27
|
+
return tempstream /* HTML */ `<datalist id="${this.getListID()}">
|
|
28
28
|
${(await this.field.generateOptions(ctx)).map(
|
|
29
29
|
({ value }) => /* HTML */ `<option>${value}</option>`
|
|
30
30
|
)}
|
|
@@ -23,10 +23,10 @@ export class BigRadioGroup extends FormFieldControl {
|
|
|
23
23
|
fctx.ctx,
|
|
24
24
|
fctx.data.raw_values
|
|
25
25
|
);
|
|
26
|
-
return tempstream/* HTML */ `<div class="bigradios">
|
|
26
|
+
return tempstream /* HTML */ `<div class="bigradios">
|
|
27
27
|
${Object.entries(this.options).map(([key, { description }]) => {
|
|
28
28
|
const id = `${this.field.name}-radio-${key}`;
|
|
29
|
-
return tempstream/* HTML */ `<input
|
|
29
|
+
return tempstream /* HTML */ `<input
|
|
30
30
|
type="radio"
|
|
31
31
|
name="${this.field.name}"
|
|
32
32
|
value="${key}"
|