@sealcode/sealgen 0.18.3 → 0.18.5
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-collection.d.ts +1 -0
- package/@types/add-crud.d.ts +3 -0
- package/@types/add-jdd-component.d.ts +1 -0
- package/@types/add-list-route.test.d.ts +1 -0
- package/@types/add-route.d.ts +3 -0
- package/@types/add-route.test.d.ts +1 -0
- package/@types/add-verbose-crud.d.ts +3 -0
- package/@types/build.d.ts +3 -0
- package/@types/builders/backend-ts-builder.d.ts +7 -0
- package/@types/builders/builder.d.ts +11 -0
- package/@types/builders/colors-builder.d.ts +10 -0
- package/@types/builders/css-builder.d.ts +19 -0
- package/@types/builders/fonts-builder.d.ts +7 -0
- package/@types/builders/frontend-ts-builder.d.ts +11 -0
- package/@types/cli.d.ts +2 -0
- package/@types/components/components.d.ts +2 -0
- package/@types/components/tabs.d.ts +2 -0
- package/@types/components/toggle-modal.d.ts +6 -0
- package/@types/crud-field-snippets.d.ts +3 -0
- package/@types/embeddable-file-extensions.d.ts +1 -0
- package/@types/esbuild-plugins/load-assets.d.ts +5 -0
- package/@types/esbuild-plugins/rewrite-asset-imports.d.ts +5 -0
- package/@types/example.test.d.ts +1 -0
- package/@types/find-css-includes.d.ts +1 -0
- package/@types/forms/controls/array.d.ts +35 -0
- package/@types/forms/controls/autocomplete.d.ts +22 -0
- package/@types/forms/controls/big-radio-group.d.ts +14 -0
- package/@types/forms/controls/checkbox-group.d.ts +21 -0
- package/@types/forms/controls/checkbox.d.ts +17 -0
- package/@types/forms/controls/checkboxed-list-input.d.ts +21 -0
- package/@types/forms/controls/checkboxed-list-input.test.d.ts +1 -0
- package/@types/forms/controls/collapsible-checkbox-group.d.ts +11 -0
- package/@types/forms/controls/collapsible-field-group.d.ts +21 -0
- package/@types/forms/controls/controls.d.ts +31 -0
- package/@types/forms/controls/derived-frame.d.ts +21 -0
- package/@types/forms/controls/derived.d.ts +13 -0
- package/@types/forms/controls/dropdown.d.ts +30 -0
- package/@types/forms/controls/editable-collection-subset.d.ts +20 -0
- package/@types/forms/controls/field-group.d.ts +23 -0
- package/@types/forms/controls/file.d.ts +13 -0
- package/@types/forms/controls/file.test.d.ts +1 -0
- package/@types/forms/controls/form-control.d.ts +20 -0
- package/@types/forms/controls/form-field-control.d.ts +13 -0
- package/@types/forms/controls/form-header.d.ts +8 -0
- package/@types/forms/controls/form-paragraph.d.ts +7 -0
- package/@types/forms/controls/frame.d.ts +17 -0
- package/@types/forms/controls/hidden-input.d.ts +9 -0
- package/@types/forms/controls/html.d.ts +11 -0
- package/@types/forms/controls/multiple-files.d.ts +40 -0
- package/@types/forms/controls/multiple-photos.d.ts +19 -0
- package/@types/forms/controls/number.d.ts +13 -0
- package/@types/forms/controls/photo.d.ts +21 -0
- package/@types/forms/controls/photo.test.d.ts +1 -0
- package/@types/forms/controls/radio.d.ts +16 -0
- package/@types/forms/controls/reverse-single-reference.d.ts +1 -0
- package/@types/forms/controls/simple-input.d.ts +33 -0
- package/@types/forms/controls/single-reference.d.ts +13 -0
- package/@types/forms/controls/single-reference.test.d.ts +1 -0
- package/@types/forms/controls/table.d.ts +34 -0
- package/@types/forms/controls/textarea.d.ts +25 -0
- package/@types/forms/controls/tickable.d.ts +25 -0
- package/@types/forms/fields/boolean.d.ts +17 -0
- package/@types/forms/fields/boolean.test.d.ts +1 -0
- package/@types/forms/fields/checkboxed-list.d.ts +21 -0
- package/@types/forms/fields/collection-field.d.ts +15 -0
- package/@types/forms/fields/email.d.ts +7 -0
- package/@types/forms/fields/email.test.d.ts +1 -0
- package/@types/forms/fields/enum-multiple.d.ts +18 -0
- package/@types/forms/fields/enum-multiple.test.d.ts +1 -0
- package/@types/forms/fields/enum.d.ts +18 -0
- package/@types/forms/fields/enum.test.d.ts +1 -0
- package/@types/forms/fields/existing-sealious-value.d.ts +6 -0
- package/@types/forms/fields/field.d.ts +48 -0
- package/@types/forms/fields/field.test.d.ts +1 -0
- package/@types/forms/fields/fields.d.ts +16 -0
- package/@types/forms/fields/file.d.ts +19 -0
- package/@types/forms/fields/file.test.d.ts +1 -0
- package/@types/forms/fields/multiple-files.d.ts +14 -0
- package/@types/forms/fields/number.d.ts +23 -0
- package/@types/forms/fields/number.test.d.ts +1 -0
- package/@types/forms/fields/pick-from-list.d.ts +14 -0
- package/@types/forms/fields/pick-from-list.test.d.ts +1 -0
- package/@types/forms/fields/proxy-field.d.ts +13 -0
- package/@types/forms/fields/regexp.d.ts +16 -0
- package/@types/forms/fields/regexp.test.d.ts +1 -0
- package/@types/forms/fields/reverse-single-reference.d.ts +13 -0
- package/@types/forms/fields/simple-form-field.d.ts +9 -0
- package/@types/forms/fields/structured-array.d.ts +14 -0
- package/@types/forms/fields/table.d.ts +13 -0
- package/@types/forms/form-types.d.ts +26 -0
- package/@types/forms/form.d.ts +31 -0
- package/@types/forms/form.test.d.ts +6 -0
- package/@types/forms/multiform.d.ts +24 -0
- package/@types/forms/multiform.test.d.ts +1 -0
- package/@types/generate-collections.d.ts +2 -0
- package/@types/generate-components.d.ts +1 -0
- package/@types/generate-routes.d.ts +5 -0
- package/@types/generate-routes.test.d.ts +1 -0
- package/@types/generate-stimulus.d.ts +1 -0
- package/@types/get-fonts.d.ts +2 -0
- package/@types/index.d.ts +46 -0
- package/@types/make-env.d.ts +1 -0
- package/@types/make-hidden-inputs.d.ts +5 -0
- package/@types/mount.d.ts +7 -0
- package/@types/notifier.d.ts +2 -0
- package/@types/page/access-control.d.ts +6 -0
- package/@types/page/default-list-filters.d.ts +18 -0
- package/@types/page/list.d.ts +48 -0
- package/@types/page/mountable-with-fields.d.ts +42 -0
- package/@types/page/mountable-with-fields.test.d.ts +1 -0
- package/@types/page/mountable.d.ts +11 -0
- package/@types/page/page.d.ts +19 -0
- package/@types/page/props-parser.d.ts +16 -0
- package/@types/page/sealious-list.d.ts +20 -0
- package/@types/page/sealious-list.test.d.ts +1 -0
- package/@types/page/stateful-page.d.ts +63 -0
- package/@types/page/stateful-page.test.d.ts +1 -0
- package/@types/register-external.d.ts +2 -0
- package/@types/register-external.test.d.ts +1 -0
- package/@types/run.d.ts +1 -0
- package/@types/sanitize.d.ts +1 -0
- package/@types/src/builder.d.ts +9 -7
- package/@types/src/register-external.d.ts +2 -0
- package/@types/src/register-external.test.d.ts +1 -0
- package/@types/target-locreq.d.ts +4 -0
- package/@types/templates/collection.d.ts +1 -0
- package/@types/templates/form.d.ts +16 -0
- package/@types/templates/jdd-component.d.ts +1 -0
- package/@types/templates/jdd-editor.d.ts +1 -0
- package/@types/templates/list.d.ts +1 -0
- package/@types/templates/long-running-process.d.ts +1 -0
- package/@types/templates/multiform.d.ts +1 -0
- package/@types/templates/page.d.ts +1 -0
- package/@types/templates/post.d.ts +1 -0
- package/@types/templates/redirect.d.ts +1 -0
- package/@types/templates/route-test.d.ts +1 -0
- package/@types/templates/shared/collection-create-form.d.ts +1 -0
- package/@types/templates/shared/collection-edit-form.d.ts +1 -0
- package/@types/templates/shared/collection-list.d.ts +16 -0
- package/@types/templates/shared/handlers/boolean.d.ts +2 -0
- package/@types/templates/shared/handlers/date.d.ts +2 -0
- package/@types/templates/shared/handlers/deep-reverse-single-reference.d.ts +2 -0
- package/@types/templates/shared/handlers/default.d.ts +2 -0
- package/@types/templates/shared/handlers/enum.d.ts +2 -0
- package/@types/templates/shared/handlers/file.d.ts +2 -0
- package/@types/templates/shared/handlers/image.d.ts +2 -0
- package/@types/templates/shared/handlers/int.d.ts +2 -0
- package/@types/templates/shared/handlers/jdd.d.ts +2 -0
- package/@types/templates/shared/handlers/single-reference.d.ts +2 -0
- package/@types/templates/shared/handlers/structured-array.d.ts +2 -0
- package/@types/templates/shared/item-delete.d.ts +1 -0
- package/@types/templates/shared/shared-crud-form-fields.d.ts +68 -0
- package/@types/templates/stateful-page.d.ts +1 -0
- package/@types/templates/stimulus-controller.d.ts +1 -0
- package/@types/templates/templates.d.ts +21 -0
- package/@types/test_utils/exec_async.d.ts +1 -0
- package/@types/test_utils/locator_is_visible.d.ts +2 -0
- package/@types/test_utils/test-on-real-app.d.ts +27 -0
- package/@types/utils/assert-throws.d.ts +1 -0
- package/@types/utils/base64.d.ts +2 -0
- package/@types/utils/browser-creator.d.ts +1 -0
- package/@types/utils/escape-url-params.d.ts +2 -0
- package/@types/utils/exec.d.ts +5 -0
- package/@types/utils/extract-fields-from-collection.d.ts +14 -0
- package/@types/utils/format-external-url.d.ts +1 -0
- package/@types/utils/import-path.d.ts +2 -0
- package/@types/utils/input-wrapper.d.ts +3 -0
- package/@types/utils/list-collections.d.ts +1 -0
- package/@types/utils/make-slug.d.ts +1 -0
- package/@types/utils/module-dirname.d.ts +1 -0
- package/@types/utils/natural-numbers.d.ts +1 -0
- package/@types/utils/prettier.d.ts +3 -0
- package/@types/utils/question.d.ts +1 -0
- package/@types/utils/render-attributes.d.ts +1 -0
- package/@types/utils/sleep.d.ts +1 -0
- package/@types/utils/translate.d.ts +3 -0
- package/@types/utils/url-with-new-params.d.ts +2 -0
- package/@types/utils/utils.d.ts +17 -0
- package/@types/utils/walk.d.ts +1 -0
- package/@types/utils/with-fallback.d.ts +2 -0
- package/@types/utils/write-file.d.ts +1 -0
- package/README.md +57 -0
- package/lib/cli.js +7 -1
- package/lib/esbuild-plugins/rewrite-asset-imports.js +0 -2
- package/lib/page/list.js +6 -2
- package/lib/register-external.js +105 -0
- package/lib/register-external.test.js +340 -0
- package/package.json +1 -1
- package/src/cli.ts +6 -0
- package/src/esbuild-plugins/rewrite-asset-imports.ts +0 -2
- package/src/page/list.ts +16 -3
- package/src/register-external.test.ts +469 -0
- package/src/register-external.ts +148 -0
- package/remove-named-imports.js +0 -68
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import assert from "assert";
|
|
2
|
+
import { promises as fs } from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { RealAppTest } from "./test_utils/test-on-real-app.js";
|
|
5
|
+
async function ensureSealgenConfig(test_app) {
|
|
6
|
+
const packageJsonPath = path.join(test_app.app_path, "package.json");
|
|
7
|
+
let packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
8
|
+
let packageJson = JSON.parse(packageJsonContent);
|
|
9
|
+
if (!packageJson.sealgen) {
|
|
10
|
+
packageJson.sealgen = {};
|
|
11
|
+
}
|
|
12
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
13
|
+
}
|
|
14
|
+
async function createMockExternalModule(test_app, moduleName, subdirectory, files) {
|
|
15
|
+
const externalModulePath = path.join(test_app.app_path, "node_modules", moduleName);
|
|
16
|
+
const targetPath = path.join(externalModulePath, subdirectory);
|
|
17
|
+
await fs.mkdir(targetPath, { recursive: true });
|
|
18
|
+
for (const file of files) {
|
|
19
|
+
await fs.writeFile(path.join(targetPath, file.name), file.content);
|
|
20
|
+
if (file.name.endsWith(".ts") && file.name.includes("stimulus")) {
|
|
21
|
+
const jsName = file.name.replace(/\.ts$/, ".js");
|
|
22
|
+
const exportName = file.name.replace(/\.stimulus\.ts$/, "");
|
|
23
|
+
await fs.writeFile(
|
|
24
|
+
path.join(targetPath, jsName),
|
|
25
|
+
`export default { connect() { console.log('Dummy JS for ${exportName}'); } }`
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
describe("register-external CLI commands", () => {
|
|
31
|
+
describe("package.json configuration", () => {
|
|
32
|
+
it("registers external controllers and verifies package.json is updated", async function() {
|
|
33
|
+
const test_app = await RealAppTest.init();
|
|
34
|
+
await ensureSealgenConfig(test_app);
|
|
35
|
+
const moduleName = "test-controller-module";
|
|
36
|
+
const subdirectory = "controllers";
|
|
37
|
+
await test_app.runSealgenCommand(
|
|
38
|
+
`register-external-controllers ${moduleName} ${subdirectory}`
|
|
39
|
+
);
|
|
40
|
+
const packageJsonPath = path.join(test_app.app_path, "package.json");
|
|
41
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
42
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
43
|
+
assert(packageJson.sealgen, "sealgen configuration should exist");
|
|
44
|
+
assert(packageJson.sealgen.controllerDirs, "controllerDirs should exist");
|
|
45
|
+
assert(
|
|
46
|
+
Array.isArray(packageJson.sealgen.controllerDirs),
|
|
47
|
+
"controllerDirs should be an array"
|
|
48
|
+
);
|
|
49
|
+
const expectedPath = `node_modules/${moduleName}/${subdirectory}`;
|
|
50
|
+
assert(
|
|
51
|
+
packageJson.sealgen.controllerDirs.includes(expectedPath),
|
|
52
|
+
`controllerDirs should contain ${expectedPath}`
|
|
53
|
+
);
|
|
54
|
+
await test_app.close();
|
|
55
|
+
}).timeout(100 * 1e3);
|
|
56
|
+
it("registers external styles and verifies package.json is updated", async function() {
|
|
57
|
+
const test_app = await RealAppTest.init();
|
|
58
|
+
await ensureSealgenConfig(test_app);
|
|
59
|
+
const moduleName = "test-style-module";
|
|
60
|
+
const subdirectory = "styles";
|
|
61
|
+
await test_app.runSealgenCommand(
|
|
62
|
+
`register-external-styles ${moduleName} ${subdirectory}`
|
|
63
|
+
);
|
|
64
|
+
const packageJsonPath = path.join(test_app.app_path, "package.json");
|
|
65
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
66
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
67
|
+
assert(packageJson.sealgen, "sealgen configuration should exist");
|
|
68
|
+
assert(packageJson.sealgen.styleDirs, "styleDirs should exist");
|
|
69
|
+
assert(Array.isArray(packageJson.sealgen.styleDirs), "styleDirs should be an array");
|
|
70
|
+
const expectedPath = `node_modules/${moduleName}/${subdirectory}`;
|
|
71
|
+
assert(
|
|
72
|
+
packageJson.sealgen.styleDirs.includes(expectedPath),
|
|
73
|
+
`styleDirs should contain ${expectedPath}`
|
|
74
|
+
);
|
|
75
|
+
await test_app.close();
|
|
76
|
+
}).timeout(100 * 1e3);
|
|
77
|
+
it("registers both controllers and styles in the same project", async function() {
|
|
78
|
+
const test_app = await RealAppTest.init();
|
|
79
|
+
await ensureSealgenConfig(test_app);
|
|
80
|
+
const controllerModule = "test-controller-module";
|
|
81
|
+
const controllerSubdir = "controllers";
|
|
82
|
+
const styleModule = "test-style-module";
|
|
83
|
+
const styleSubdir = "styles";
|
|
84
|
+
await test_app.runSealgenCommand(
|
|
85
|
+
`register-external-controllers ${controllerModule} ${controllerSubdir}`
|
|
86
|
+
);
|
|
87
|
+
await test_app.runSealgenCommand(
|
|
88
|
+
`register-external-styles ${styleModule} ${styleSubdir}`
|
|
89
|
+
);
|
|
90
|
+
const packageJsonPath = path.join(test_app.app_path, "package.json");
|
|
91
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
92
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
93
|
+
assert(packageJson.sealgen, "sealgen configuration should exist");
|
|
94
|
+
assert(packageJson.sealgen.controllerDirs, "controllerDirs should exist");
|
|
95
|
+
assert(packageJson.sealgen.styleDirs, "styleDirs should exist");
|
|
96
|
+
const expectedControllerPath = `node_modules/${controllerModule}/${controllerSubdir}`;
|
|
97
|
+
const expectedStylePath = `node_modules/${styleModule}/${styleSubdir}`;
|
|
98
|
+
assert(
|
|
99
|
+
packageJson.sealgen.controllerDirs.includes(expectedControllerPath),
|
|
100
|
+
`controllerDirs should contain ${expectedControllerPath}`
|
|
101
|
+
);
|
|
102
|
+
assert(
|
|
103
|
+
packageJson.sealgen.styleDirs.includes(expectedStylePath),
|
|
104
|
+
`styleDirs should contain ${expectedStylePath}`
|
|
105
|
+
);
|
|
106
|
+
await test_app.close();
|
|
107
|
+
}).timeout(100 * 1e3);
|
|
108
|
+
it("handles duplicate registrations gracefully", async function() {
|
|
109
|
+
const test_app = await RealAppTest.init();
|
|
110
|
+
await ensureSealgenConfig(test_app);
|
|
111
|
+
const moduleName = "test-duplicate-module";
|
|
112
|
+
const subdirectory = "controllers";
|
|
113
|
+
await test_app.runSealgenCommand(
|
|
114
|
+
`register-external-controllers ${moduleName} ${subdirectory}`
|
|
115
|
+
);
|
|
116
|
+
await test_app.runSealgenCommand(
|
|
117
|
+
`register-external-controllers ${moduleName} ${subdirectory}`
|
|
118
|
+
);
|
|
119
|
+
const packageJsonPath = path.join(test_app.app_path, "package.json");
|
|
120
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
121
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
122
|
+
assert(packageJson.sealgen, "sealgen configuration should exist");
|
|
123
|
+
assert(packageJson.sealgen.controllerDirs, "controllerDirs should exist");
|
|
124
|
+
const expectedPath = `node_modules/${moduleName}/${subdirectory}`;
|
|
125
|
+
const controllerDirs = packageJson.sealgen.controllerDirs;
|
|
126
|
+
const occurrences = controllerDirs.filter((dir) => dir === expectedPath).length;
|
|
127
|
+
assert(
|
|
128
|
+
occurrences === 1,
|
|
129
|
+
`controllerDirs should contain ${expectedPath} exactly once, found ${occurrences} times`
|
|
130
|
+
);
|
|
131
|
+
await test_app.close();
|
|
132
|
+
}).timeout(100 * 1e3);
|
|
133
|
+
it("preserves existing sealgen configuration when adding new entries", async function() {
|
|
134
|
+
const test_app = await RealAppTest.init();
|
|
135
|
+
const packageJsonPath = path.join(test_app.app_path, "package.json");
|
|
136
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
137
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
138
|
+
packageJson.sealgen = {
|
|
139
|
+
controllerDirs: ["node_modules/existing-controller/controllers"],
|
|
140
|
+
styleDirs: ["node_modules/existing-style/styles"]
|
|
141
|
+
};
|
|
142
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
143
|
+
const newControllerModule = "new-controller-module";
|
|
144
|
+
const newStyleModule = "new-style-module";
|
|
145
|
+
await test_app.runSealgenCommand(
|
|
146
|
+
`register-external-controllers ${newControllerModule} controllers`
|
|
147
|
+
);
|
|
148
|
+
await test_app.runSealgenCommand(`register-external-styles ${newStyleModule} styles`);
|
|
149
|
+
const updatedPackageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
150
|
+
const updatedPackageJson = JSON.parse(updatedPackageJsonContent);
|
|
151
|
+
assert(updatedPackageJson.sealgen, "sealgen configuration should exist");
|
|
152
|
+
assert(updatedPackageJson.sealgen.controllerDirs, "controllerDirs should exist");
|
|
153
|
+
assert(updatedPackageJson.sealgen.styleDirs, "styleDirs should exist");
|
|
154
|
+
assert(
|
|
155
|
+
updatedPackageJson.sealgen.controllerDirs.includes(
|
|
156
|
+
"node_modules/existing-controller/controllers"
|
|
157
|
+
),
|
|
158
|
+
"Existing controller directory should be preserved"
|
|
159
|
+
);
|
|
160
|
+
assert(
|
|
161
|
+
updatedPackageJson.sealgen.styleDirs.includes("node_modules/existing-style/styles"),
|
|
162
|
+
"Existing style directory should be preserved"
|
|
163
|
+
);
|
|
164
|
+
assert(
|
|
165
|
+
updatedPackageJson.sealgen.controllerDirs.includes(
|
|
166
|
+
`node_modules/${newControllerModule}/controllers`
|
|
167
|
+
),
|
|
168
|
+
"New controller directory should be added"
|
|
169
|
+
);
|
|
170
|
+
assert(
|
|
171
|
+
updatedPackageJson.sealgen.styleDirs.includes(
|
|
172
|
+
`node_modules/${newStyleModule}/styles`
|
|
173
|
+
),
|
|
174
|
+
"New style directory should be added"
|
|
175
|
+
);
|
|
176
|
+
await test_app.close();
|
|
177
|
+
}).timeout(100 * 1e3);
|
|
178
|
+
});
|
|
179
|
+
describe("build integration", () => {
|
|
180
|
+
it("registers external controllers and verifies they are included in build", async function() {
|
|
181
|
+
const test_app = await RealAppTest.init();
|
|
182
|
+
await ensureSealgenConfig(test_app);
|
|
183
|
+
const externalModuleName = "test-external-controllers";
|
|
184
|
+
await createMockExternalModule(test_app, externalModuleName, "controllers", [
|
|
185
|
+
{
|
|
186
|
+
name: "test-external.stimulus.ts",
|
|
187
|
+
content: `
|
|
188
|
+
import { Controller } from "stimulus";
|
|
189
|
+
|
|
190
|
+
export default class TestExternalController extends Controller {
|
|
191
|
+
static targets = ["output"];
|
|
192
|
+
|
|
193
|
+
connect() {
|
|
194
|
+
console.log("External controller connected!");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
`
|
|
198
|
+
}
|
|
199
|
+
]);
|
|
200
|
+
await test_app.runSealgenCommand(
|
|
201
|
+
`register-external-controllers ${externalModuleName} controllers`
|
|
202
|
+
);
|
|
203
|
+
await test_app.runSealgenCommand("build");
|
|
204
|
+
const controllersFilePath = path.join(test_app.app_path, "src/front/controllers.ts");
|
|
205
|
+
const controllersContent = await fs.readFile(controllersFilePath, "utf-8");
|
|
206
|
+
assert(
|
|
207
|
+
controllersContent.includes(
|
|
208
|
+
`import { default as TestExternal } from "./../../node_modules/${externalModuleName}/controllers/test-external.stimulus.js"`
|
|
209
|
+
),
|
|
210
|
+
"External controller should be imported in generated controllers file"
|
|
211
|
+
);
|
|
212
|
+
assert(
|
|
213
|
+
controllersContent.includes(`application.register("test-external", TestExternal);`),
|
|
214
|
+
"External controller should be registered in generated controllers file"
|
|
215
|
+
);
|
|
216
|
+
const bundlePath = path.join(test_app.app_path, "public/dist/bundle.js");
|
|
217
|
+
assert(
|
|
218
|
+
await fs.stat(bundlePath).then(() => true).catch(() => false),
|
|
219
|
+
"Bundle should be generated"
|
|
220
|
+
);
|
|
221
|
+
await test_app.close();
|
|
222
|
+
}).timeout(100 * 1e3);
|
|
223
|
+
it("registers external styles and verifies they are included in build", async function() {
|
|
224
|
+
const test_app = await RealAppTest.init();
|
|
225
|
+
await ensureSealgenConfig(test_app);
|
|
226
|
+
const externalModuleName = "test-external-styles";
|
|
227
|
+
await createMockExternalModule(test_app, externalModuleName, "styles", [
|
|
228
|
+
{
|
|
229
|
+
name: "external.css",
|
|
230
|
+
content: `
|
|
231
|
+
.external-style {
|
|
232
|
+
color: red;
|
|
233
|
+
background: blue;
|
|
234
|
+
}
|
|
235
|
+
`
|
|
236
|
+
}
|
|
237
|
+
]);
|
|
238
|
+
await test_app.runSealgenCommand(
|
|
239
|
+
`register-external-styles ${externalModuleName} styles`
|
|
240
|
+
);
|
|
241
|
+
await test_app.runSealgenCommand("build");
|
|
242
|
+
const styleEntrypointPath = path.join(
|
|
243
|
+
test_app.app_path,
|
|
244
|
+
"src/style-entrypoints/default.entrypoint.css"
|
|
245
|
+
);
|
|
246
|
+
const styleEntrypointContent = await fs.readFile(styleEntrypointPath, "utf-8");
|
|
247
|
+
assert(
|
|
248
|
+
styleEntrypointContent.includes(
|
|
249
|
+
`@import "../../node_modules/${externalModuleName}/styles/external.css"`
|
|
250
|
+
),
|
|
251
|
+
"External CSS should be imported in generated style entrypoint"
|
|
252
|
+
);
|
|
253
|
+
const cssOutputPath = path.join(
|
|
254
|
+
test_app.app_path,
|
|
255
|
+
"public/dist/default.entrypoint.css"
|
|
256
|
+
);
|
|
257
|
+
assert(
|
|
258
|
+
await fs.stat(cssOutputPath).then(() => true).catch(() => false),
|
|
259
|
+
"CSS should be generated"
|
|
260
|
+
);
|
|
261
|
+
await test_app.close();
|
|
262
|
+
}).timeout(100 * 1e3);
|
|
263
|
+
it("registers both external controllers and styles and verifies complete build integration", async function() {
|
|
264
|
+
const test_app = await RealAppTest.init();
|
|
265
|
+
await ensureSealgenConfig(test_app);
|
|
266
|
+
const controllerModuleName = "test-external-controllers";
|
|
267
|
+
const styleModuleName = "test-external-styles";
|
|
268
|
+
await createMockExternalModule(test_app, controllerModuleName, "controllers", [
|
|
269
|
+
{
|
|
270
|
+
name: "combined-test.stimulus.ts",
|
|
271
|
+
content: `
|
|
272
|
+
import { Controller } from "stimulus";
|
|
273
|
+
|
|
274
|
+
export default class CombinedTestController extends Controller {
|
|
275
|
+
static targets = ["output"];
|
|
276
|
+
|
|
277
|
+
connect() {
|
|
278
|
+
console.log("Combined test controller connected!");
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
`
|
|
282
|
+
}
|
|
283
|
+
]);
|
|
284
|
+
await createMockExternalModule(test_app, styleModuleName, "styles", [
|
|
285
|
+
{
|
|
286
|
+
name: "combined-external.css",
|
|
287
|
+
content: `
|
|
288
|
+
.combined-external-style {
|
|
289
|
+
color: green;
|
|
290
|
+
background: yellow;
|
|
291
|
+
}
|
|
292
|
+
`
|
|
293
|
+
}
|
|
294
|
+
]);
|
|
295
|
+
await test_app.runSealgenCommand(
|
|
296
|
+
`register-external-controllers ${controllerModuleName} controllers`
|
|
297
|
+
);
|
|
298
|
+
await test_app.runSealgenCommand(`register-external-styles ${styleModuleName} styles`);
|
|
299
|
+
await test_app.runSealgenCommand("build");
|
|
300
|
+
const controllersFilePath = path.join(test_app.app_path, "src/front/controllers.ts");
|
|
301
|
+
const controllersContent = await fs.readFile(controllersFilePath, "utf-8");
|
|
302
|
+
assert(
|
|
303
|
+
controllersContent.includes(
|
|
304
|
+
`import { default as CombinedTest } from "./../../node_modules/${controllerModuleName}/controllers/combined-test.stimulus.js"`
|
|
305
|
+
),
|
|
306
|
+
"Combined test controller should be imported"
|
|
307
|
+
);
|
|
308
|
+
assert(
|
|
309
|
+
controllersContent.includes(`application.register("combined-test", CombinedTest);`),
|
|
310
|
+
"Combined test controller should be registered"
|
|
311
|
+
);
|
|
312
|
+
const styleEntrypointPath = path.join(
|
|
313
|
+
test_app.app_path,
|
|
314
|
+
"src/style-entrypoints/default.entrypoint.css"
|
|
315
|
+
);
|
|
316
|
+
const styleEntrypointContent = await fs.readFile(styleEntrypointPath, "utf-8");
|
|
317
|
+
assert(
|
|
318
|
+
styleEntrypointContent.includes(
|
|
319
|
+
`@import "../../node_modules/${styleModuleName}/styles/combined-external.css"`
|
|
320
|
+
),
|
|
321
|
+
"Combined external CSS should be imported"
|
|
322
|
+
);
|
|
323
|
+
const bundlePath = path.join(test_app.app_path, "public/dist/bundle.js");
|
|
324
|
+
const cssOutputPath = path.join(
|
|
325
|
+
test_app.app_path,
|
|
326
|
+
"public/dist/default.entrypoint.css"
|
|
327
|
+
);
|
|
328
|
+
assert(
|
|
329
|
+
await fs.stat(bundlePath).then(() => true).catch(() => false),
|
|
330
|
+
"Bundle should be generated"
|
|
331
|
+
);
|
|
332
|
+
assert(
|
|
333
|
+
await fs.stat(cssOutputPath).then(() => true).catch(() => false),
|
|
334
|
+
"CSS should be generated"
|
|
335
|
+
);
|
|
336
|
+
await test_app.close();
|
|
337
|
+
}).timeout(100 * 1e3);
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
//# sourceMappingURL=register-external.test.js.map
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -12,6 +12,10 @@ import { generateRoutes } from "./generate-routes.js";
|
|
|
12
12
|
import { getFonts } from "./get-fonts.js";
|
|
13
13
|
import { makeEnv } from "./make-env.js";
|
|
14
14
|
import { crudFieldSnippets } from "./crud-field-snippets.js";
|
|
15
|
+
import {
|
|
16
|
+
registerExternalControllers,
|
|
17
|
+
registerExternalStyles,
|
|
18
|
+
} from "./register-external.js";
|
|
15
19
|
|
|
16
20
|
const actions: Record<
|
|
17
21
|
string,
|
|
@@ -37,6 +41,8 @@ const actions: Record<
|
|
|
37
41
|
"add-component": addJDDComponent,
|
|
38
42
|
"get-fonts": getFonts,
|
|
39
43
|
"crud-field-snippets": crudFieldSnippets,
|
|
44
|
+
"register-external-controllers": registerExternalControllers,
|
|
45
|
+
"register-external-styles": registerExternalStyles,
|
|
40
46
|
};
|
|
41
47
|
|
|
42
48
|
void (async function () {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { promises as fs } from "fs";
|
|
2
2
|
import { extname, resolve } from "node:path";
|
|
3
3
|
import { embeddable_file_extensions } from "../embeddable-file-extensions.js";
|
|
4
|
-
import { removeNamedImports } from "../../remove-named-imports.js";
|
|
5
4
|
import { PluginBuild } from "esbuild";
|
|
6
5
|
|
|
7
6
|
export const rewrite_asset_imports_plugin = (project_dir: string) => ({
|
|
@@ -34,7 +33,6 @@ export const rewrite_asset_imports_plugin = (project_dir: string) => ({
|
|
|
34
33
|
}
|
|
35
34
|
);
|
|
36
35
|
|
|
37
|
-
contents = removeNamedImports(contents) as string;
|
|
38
36
|
return {
|
|
39
37
|
contents,
|
|
40
38
|
loader: extname(args.path) === ".tsx" ? "tsx" : "ts",
|
package/src/page/list.ts
CHANGED
|
@@ -198,10 +198,18 @@ export abstract class ListPage<
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
makeSortLink(
|
|
201
|
+
makeSortLink(
|
|
202
|
+
ctx: Context,
|
|
203
|
+
field: string,
|
|
204
|
+
order: "asc" | "desc" | null
|
|
205
|
+
): string {
|
|
202
206
|
const url = new URL(ctx.url, "https://example.com");
|
|
203
207
|
const params = qs.parse(url.search.slice(1));
|
|
204
|
-
|
|
208
|
+
if (order === null) {
|
|
209
|
+
delete params.sort;
|
|
210
|
+
} else {
|
|
211
|
+
params.sort = encodeSort(field, order);
|
|
212
|
+
}
|
|
205
213
|
url.search = qs.stringify(params);
|
|
206
214
|
return url.pathname + url.search;
|
|
207
215
|
}
|
|
@@ -234,7 +242,12 @@ export abstract class ListPage<
|
|
|
234
242
|
const current_sort = await this.getSort(ctx);
|
|
235
243
|
const current_order =
|
|
236
244
|
current_sort?.field == field ? current_sort.order : null;
|
|
237
|
-
const order =
|
|
245
|
+
const order =
|
|
246
|
+
current_order === "asc" // cycles the sort order: null → "asc" → "desc" → null → ...
|
|
247
|
+
? "desc"
|
|
248
|
+
: current_order === null
|
|
249
|
+
? "asc"
|
|
250
|
+
: null;
|
|
238
251
|
return /* HTML */ `<th>
|
|
239
252
|
<a href="${this.makeSortLink(ctx, field, order)}"
|
|
240
253
|
>${label}
|