@aerogel/cli 0.0.0-next.59bf5f7cc06e728d0cf6c00de28f1da48d7d6b8e → 0.0.0-next.60462e474474f4e52d52d457f9150df63c117214
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/bin/gel +4 -0
- package/dist/aerogel-cli.d.ts +2 -2
- package/dist/aerogel-cli.js +793 -0
- package/dist/aerogel-cli.js.map +1 -0
- package/package.json +27 -33
- package/src/cli.ts +28 -6
- package/src/commands/Command.ts +14 -9
- package/src/commands/create.test.ts +14 -6
- package/src/commands/create.ts +25 -14
- package/src/commands/generate-component.test.ts +51 -4
- package/src/commands/generate-component.ts +167 -26
- package/src/commands/generate-model.test.ts +3 -3
- package/src/commands/generate-model.ts +24 -27
- package/src/commands/generate-service.test.ts +21 -0
- package/src/commands/generate-service.ts +151 -0
- package/src/commands/info.ts +15 -0
- package/src/commands/install.test.ts +27 -0
- package/src/commands/install.ts +32 -0
- package/src/lib/App.ts +67 -9
- package/src/lib/Editor.ts +57 -0
- package/src/lib/File.mock.ts +7 -11
- package/src/lib/File.ts +9 -3
- package/src/lib/Log.mock.ts +5 -8
- package/src/lib/Log.test.ts +4 -4
- package/src/lib/Log.ts +13 -11
- package/src/lib/Shell.mock.ts +3 -3
- package/src/lib/Shell.ts +2 -2
- package/src/lib/Template.ts +24 -17
- package/src/lib/utils/app.ts +15 -0
- package/src/lib/utils/edit.ts +44 -0
- package/src/lib/utils/paths.ts +42 -0
- package/src/plugins/Plugin.ts +159 -0
- package/src/plugins/Solid.ts +71 -0
- package/src/plugins/Soukai.ts +19 -0
- package/src/testing/setup.ts +56 -27
- package/templates/app/.github/workflows/ci.yml +16 -4
- package/templates/app/.nvmrc +1 -1
- package/templates/app/.vscode/launch.json +17 -0
- package/templates/app/.vscode/settings.json +10 -0
- package/templates/app/README.md +3 -0
- package/templates/app/cypress/cypress.config.ts +14 -0
- package/templates/app/cypress/support/e2e.ts +1 -3
- package/templates/app/cypress/tsconfig.json +7 -8
- package/templates/app/index.html +5 -4
- package/templates/app/package.json +42 -19
- package/templates/app/src/App.vue +6 -4
- package/templates/app/src/assets/css/main.css +4 -0
- package/templates/app/src/assets/public/robots.txt +2 -0
- package/templates/app/src/main.ts +4 -4
- package/templates/app/src/types/globals.d.ts +0 -1
- package/templates/app/tsconfig.json +3 -9
- package/templates/app/vite.config.ts +15 -8
- package/templates/component-button/[component.name].vue +42 -0
- package/templates/component-button-story/[component.name].story.vue +77 -0
- package/templates/component-checkbox/[component.name].vue +34 -0
- package/templates/component-checkbox-story/[component.name].story.vue +63 -0
- package/templates/component-input/[component.name].vue +17 -0
- package/templates/component-input-story/[component.name].story.vue +63 -0
- package/templates/service/[service.name].ts +8 -0
- package/.eslintrc.js +0 -7
- package/bin/ag +0 -4
- package/dist/aerogel-cli.cjs.js +0 -2
- package/dist/aerogel-cli.cjs.js.map +0 -1
- package/dist/aerogel-cli.esm.js +0 -2
- package/dist/aerogel-cli.esm.js.map +0 -1
- package/noeldemartin.config.js +0 -4
- package/src/lib/utils.test.ts +0 -33
- package/src/lib/utils.ts +0 -44
- package/templates/app/cypress.config.ts +0 -8
- package/templates/app/postcss.config.js +0 -6
- package/templates/app/src/assets/styles.css +0 -3
- package/templates/app/tailwind.config.js +0 -5
- package/tsconfig.json +0 -11
- package/vite.config.ts +0 -14
- /package/src/{main.ts → index.ts} +0 -0
|
@@ -1,24 +1,31 @@
|
|
|
1
|
+
import { URL, fileURLToPath } from 'node:url';
|
|
2
|
+
|
|
1
3
|
import Aerogel, { AerogelResolver } from '@aerogel/vite';
|
|
2
4
|
import Components from 'unplugin-vue-components/vite';
|
|
3
5
|
import I18n from '@intlify/unplugin-vue-i18n/vite';
|
|
4
6
|
import Icons from 'unplugin-icons/vite';
|
|
5
7
|
import IconsResolver from 'unplugin-icons/resolver';
|
|
6
|
-
import {
|
|
8
|
+
import { defineConfig } from 'vitest/config';
|
|
7
9
|
|
|
8
|
-
export default {
|
|
10
|
+
export default defineConfig({
|
|
11
|
+
build: { sourcemap: true },
|
|
12
|
+
publicDir: fileURLToPath(new URL('./src/assets/public/', import.meta.url)),
|
|
9
13
|
plugins: [
|
|
10
|
-
Aerogel(),
|
|
14
|
+
Aerogel({ name: '<% app.name %>' }),
|
|
11
15
|
Components({
|
|
12
|
-
dirs: ['src/pages'],
|
|
13
16
|
dts: false,
|
|
14
17
|
resolvers: [AerogelResolver(), IconsResolver()],
|
|
15
18
|
}),
|
|
16
|
-
I18n({ include:
|
|
17
|
-
Icons(
|
|
19
|
+
I18n({ include: fileURLToPath(new URL('./src/lang/**/*.yaml', import.meta.url)) }),
|
|
20
|
+
Icons({
|
|
21
|
+
iconCustomizer(_, __, props) {
|
|
22
|
+
props['aria-hidden'] = 'true';
|
|
23
|
+
},
|
|
24
|
+
}),
|
|
18
25
|
],
|
|
19
26
|
resolve: {
|
|
20
27
|
alias: {
|
|
21
|
-
'@':
|
|
28
|
+
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
|
22
29
|
},
|
|
23
30
|
},
|
|
24
|
-
};
|
|
31
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<HeadlessButton :class="variantClasses" :disabled="disabled">
|
|
3
|
+
<slot />
|
|
4
|
+
</HeadlessButton>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import { Colors, booleanProp, enumProp, removeInteractiveClasses } from '@aerogel/core';
|
|
9
|
+
import { computed } from 'vue';
|
|
10
|
+
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
color: enumProp(Colors, Colors.Primary),
|
|
13
|
+
disabled: booleanProp(),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const colorClasses = computed(() => {
|
|
17
|
+
switch (props.color) {
|
|
18
|
+
case Colors.Secondary:
|
|
19
|
+
// Add your custom color classes here.
|
|
20
|
+
return '';
|
|
21
|
+
case Colors.Clear:
|
|
22
|
+
// Add your custom color classes here.
|
|
23
|
+
return '';
|
|
24
|
+
case Colors.Danger:
|
|
25
|
+
// Add your custom color classes here.
|
|
26
|
+
return '';
|
|
27
|
+
case Colors.Primary:
|
|
28
|
+
default:
|
|
29
|
+
// Add your custom color classes here.
|
|
30
|
+
return '';
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const variantClasses = computed(() => {
|
|
35
|
+
if (props.disabled) {
|
|
36
|
+
// Add additional classes for disabled state here.
|
|
37
|
+
return removeInteractiveClasses(colorClasses.value);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return colorClasses.value;
|
|
41
|
+
});
|
|
42
|
+
</script>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Story :layout="{ type: 'grid' }">
|
|
3
|
+
<Variant title="Playground">
|
|
4
|
+
<<% component.name %> :color="color">
|
|
5
|
+
{{ content }}
|
|
6
|
+
</<% component.name %>>
|
|
7
|
+
|
|
8
|
+
<template #controls>
|
|
9
|
+
<HstText v-model="content" title="Content" />
|
|
10
|
+
<HstSelect v-model="color" title="Color" :options="colorOptions" />
|
|
11
|
+
</template>
|
|
12
|
+
</Variant>
|
|
13
|
+
|
|
14
|
+
<Variant title="Default">
|
|
15
|
+
<<% component.name %>>
|
|
16
|
+
Click me!
|
|
17
|
+
</<% component.name %>>
|
|
18
|
+
</Variant>
|
|
19
|
+
|
|
20
|
+
<Variant title="Hover">
|
|
21
|
+
<<% component.name %> class=":hover">
|
|
22
|
+
Click me!
|
|
23
|
+
</<% component.name %>>
|
|
24
|
+
</Variant>
|
|
25
|
+
|
|
26
|
+
<Variant title="Focus">
|
|
27
|
+
<<% component.name %> class=":focus :focus-visible">
|
|
28
|
+
Click me!
|
|
29
|
+
</<% component.name %>>
|
|
30
|
+
</Variant>
|
|
31
|
+
|
|
32
|
+
<Variant title="Disabled">
|
|
33
|
+
<<% component.name %> disabled>
|
|
34
|
+
You can't click me
|
|
35
|
+
</<% component.name %>>
|
|
36
|
+
</Variant>
|
|
37
|
+
|
|
38
|
+
<Variant title="Colors" :layout="{ width: '300px' }">
|
|
39
|
+
<div class="flex items-center gap-2">
|
|
40
|
+
<<% component.name %> color="primary">
|
|
41
|
+
Primary
|
|
42
|
+
</<% component.name %>>
|
|
43
|
+
<<% component.name %> color="secondary">
|
|
44
|
+
Secondary
|
|
45
|
+
</<% component.name %>>
|
|
46
|
+
<<% component.name %> color="danger">
|
|
47
|
+
Danger
|
|
48
|
+
</<% component.name %>>
|
|
49
|
+
<<% component.name %> color="clear">
|
|
50
|
+
Clear
|
|
51
|
+
</<% component.name %>>
|
|
52
|
+
</div>
|
|
53
|
+
</Variant>
|
|
54
|
+
</Story>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
<script setup lang="ts">
|
|
58
|
+
import { Colors } from '@aerogel/core';
|
|
59
|
+
import { invert } from '@noeldemartin/utils';
|
|
60
|
+
import { ref } from 'vue';
|
|
61
|
+
import type { Color } from '@aerogel/core';
|
|
62
|
+
|
|
63
|
+
const content = ref('Click me!');
|
|
64
|
+
const color = ref<Color>(Colors.Primary);
|
|
65
|
+
const colorOptions = invert(Colors);
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<style>
|
|
69
|
+
.story-<% component.slug %> {
|
|
70
|
+
grid-template-columns: repeat(2, 300px) !important;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.story-<% component.slug %> .variant-playground,
|
|
74
|
+
.story-<% component.slug %> .variant-colors{
|
|
75
|
+
grid-column: 1 / -1;
|
|
76
|
+
}
|
|
77
|
+
</style>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<HeadlessInput
|
|
3
|
+
ref="$input"
|
|
4
|
+
:name="name"
|
|
5
|
+
:class="className"
|
|
6
|
+
:label="label"
|
|
7
|
+
>
|
|
8
|
+
<HeadlessInputInput
|
|
9
|
+
v-bind="attrs"
|
|
10
|
+
type="checkbox"
|
|
11
|
+
/>
|
|
12
|
+
<div v-if="$slots.default">
|
|
13
|
+
<HeadlessInputLabel>
|
|
14
|
+
<slot />
|
|
15
|
+
</HeadlessInputLabel>
|
|
16
|
+
<HeadlessInputError />
|
|
17
|
+
</div>
|
|
18
|
+
</HeadlessInput>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import { HeadlessInputLabel, componentRef, stringProp, useInputAttrs } from '@aerogel/core';
|
|
23
|
+
import type { IHeadlessInput } from '@aerogel/core';
|
|
24
|
+
|
|
25
|
+
defineOptions({ inheritAttrs: false });
|
|
26
|
+
defineProps({
|
|
27
|
+
name: stringProp(),
|
|
28
|
+
label: stringProp(),
|
|
29
|
+
inputClass: stringProp(''),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const $input = componentRef<IHeadlessInput>();
|
|
33
|
+
const [attrs, className] = useInputAttrs();
|
|
34
|
+
</script>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Story group="base" :layout="{ type: 'grid' }">
|
|
3
|
+
<Variant title="Playground">
|
|
4
|
+
<Form :form="form" class="m-1">
|
|
5
|
+
<<% component.name %> name="accept" :form="form">
|
|
6
|
+
{{ label }}
|
|
7
|
+
</<% component.name %>>
|
|
8
|
+
</Form>
|
|
9
|
+
|
|
10
|
+
<template #controls>
|
|
11
|
+
<HstText v-model="label" title="Label" />
|
|
12
|
+
</template>
|
|
13
|
+
</Variant>
|
|
14
|
+
|
|
15
|
+
<Variant title="Default">
|
|
16
|
+
<<% component.name %> class="m-1">
|
|
17
|
+
Accept Terms & Conditions
|
|
18
|
+
</<% component.name %>>
|
|
19
|
+
</Variant>
|
|
20
|
+
|
|
21
|
+
<Variant title="Hover">
|
|
22
|
+
<<% component.name %> class="m-1" input-class=":hover">
|
|
23
|
+
Accept Terms & Conditions
|
|
24
|
+
</<% component.name %>>
|
|
25
|
+
</Variant>
|
|
26
|
+
|
|
27
|
+
<Variant title="Focus">
|
|
28
|
+
<<% component.name %> class="m-1" input-class=":focus :focus-visible">
|
|
29
|
+
Accept Terms & Conditions
|
|
30
|
+
</<% component.name %>>
|
|
31
|
+
</Variant>
|
|
32
|
+
|
|
33
|
+
<Variant title="Error">
|
|
34
|
+
<Form :form="errorForm" class="m-1">
|
|
35
|
+
<<% component.name %> name="accept">
|
|
36
|
+
Accept Terms & Conditions
|
|
37
|
+
</<% component.name %>>
|
|
38
|
+
</Form>
|
|
39
|
+
</Variant>
|
|
40
|
+
</Story>
|
|
41
|
+
</template>
|
|
42
|
+
|
|
43
|
+
<script setup lang="ts">
|
|
44
|
+
import { requiredBooleanInput, useForm } from '@aerogel/core';
|
|
45
|
+
import { ref } from 'vue';
|
|
46
|
+
|
|
47
|
+
const form = useForm({ accept: requiredBooleanInput(true) });
|
|
48
|
+
const errorForm = useForm({ accept: requiredBooleanInput() });
|
|
49
|
+
const label = ref('Accept Terms & Conditions');
|
|
50
|
+
|
|
51
|
+
form.submit();
|
|
52
|
+
errorForm.submit();
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<style>
|
|
56
|
+
.story-<% component.slug %> {
|
|
57
|
+
grid-template-columns: repeat(2, 300px) !important;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.story-<% component.slug %> .variant-playground {
|
|
61
|
+
grid-column: 1 / -1;
|
|
62
|
+
}
|
|
63
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<HeadlessInput v-bind="props">
|
|
3
|
+
<HeadlessInputLabel />
|
|
4
|
+
<HeadlessInputInput v-bind="attrs" />
|
|
5
|
+
<HeadlessInputDescription />
|
|
6
|
+
<HeadlessInputError />
|
|
7
|
+
</HeadlessInput>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
import { useInputAttrs, useInputProps } from '@aerogel/core';
|
|
12
|
+
|
|
13
|
+
defineOptions({ inheritAttrs: false });
|
|
14
|
+
|
|
15
|
+
const props = defineProps(useInputProps());
|
|
16
|
+
const [attrs] = useInputAttrs();
|
|
17
|
+
</script>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Story :layout="{ type: 'grid' }">
|
|
3
|
+
<Variant title="Playground">
|
|
4
|
+
<Form :form="form">
|
|
5
|
+
<<% component.name %> name="food" :label="label" :placeholder="placeholder" />
|
|
6
|
+
</Form>
|
|
7
|
+
|
|
8
|
+
<template #controls>
|
|
9
|
+
<HstText v-model="label" title="Label" />
|
|
10
|
+
<HstText v-model="placeholder" title="Placeholder" />
|
|
11
|
+
<HstCheckbox v-model="hasErrors" title="Errors" />
|
|
12
|
+
</template>
|
|
13
|
+
</Variant>
|
|
14
|
+
|
|
15
|
+
<Variant title="Default">
|
|
16
|
+
<<% component.name %> label="What's the best food?" placeholder="Ramen" />
|
|
17
|
+
</Variant>
|
|
18
|
+
|
|
19
|
+
<Variant title="Hover">
|
|
20
|
+
<<% component.name %> label="What's the best food?" placeholder="Ramen" input-class=":hover" />
|
|
21
|
+
</Variant>
|
|
22
|
+
|
|
23
|
+
<Variant title="Focus">
|
|
24
|
+
<<% component.name %> label="What's the best food?" placeholder="Ramen" input-class=":focus :focus-visible" />
|
|
25
|
+
</Variant>
|
|
26
|
+
|
|
27
|
+
<Variant title="Error">
|
|
28
|
+
<Form :form="errorForm">
|
|
29
|
+
<<% component.name %>
|
|
30
|
+
name="food"
|
|
31
|
+
label="What's the best food?"
|
|
32
|
+
placeholder="Ramen"
|
|
33
|
+
class=":focus :focus-visible"
|
|
34
|
+
/>
|
|
35
|
+
</Form>
|
|
36
|
+
</Variant>
|
|
37
|
+
</Story>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script setup lang="ts">
|
|
41
|
+
import { requiredStringInput, useForm } from '@aerogel/core';
|
|
42
|
+
import { ref, watchEffect } from 'vue';
|
|
43
|
+
|
|
44
|
+
const form = useForm({ food: requiredStringInput() });
|
|
45
|
+
const errorForm = useForm({ food: requiredStringInput() });
|
|
46
|
+
const label = ref('What\'s the best food?');
|
|
47
|
+
const placeholder = ref('Ramen');
|
|
48
|
+
const hasErrors = ref(false);
|
|
49
|
+
|
|
50
|
+
errorForm.submit();
|
|
51
|
+
|
|
52
|
+
watchEffect(() => (hasErrors.value ? form.submit() : form.reset()));
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<style>
|
|
56
|
+
.story-<% component.slug %> {
|
|
57
|
+
grid-template-columns: repeat(2, 300px) !important;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.story-<% component.slug %> .variant-playground {
|
|
61
|
+
grid-column: 1 / -1;
|
|
62
|
+
}
|
|
63
|
+
</style>
|
package/.eslintrc.js
DELETED
package/bin/ag
DELETED
package/dist/aerogel-cli.cjs.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("commander"),t=require("@babel/runtime/helpers/defineProperty"),n=require("@noeldemartin/utils"),s=require("fs"),i=require("path");require("core-js/modules/esnext.async-iterator.for-each.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.for-each.js"),require("core-js/modules/esnext.async-iterator.find.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.async-iterator.map.js"),require("core-js/modules/esnext.iterator.map.js");var r=require("chalk"),o=require("readline");require("core-js/modules/esnext.async-iterator.reduce.js"),require("core-js/modules/esnext.iterator.reduce.js");var a=require("mustache"),l=require("child_process");function c(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var d=c(t);var u=n.facade(new class{contains(e,t){return!!this.read(e)?.includes(t)}exists(e){return s.existsSync(e)}read(e){return this.isFile(e)?s.readFileSync(e).toString():null}getFiles(e){const t=s.readdirSync(e,{withFileTypes:!0}),n=[];for(const s of t){const t=i.resolve(e,s.name);s.isDirectory()?n.push(...this.getFiles(t)):n.push(t)}return n}isDirectory(e){return this.exists(e)&&s.lstatSync(e).isDirectory()}isFile(e){return this.exists(e)&&s.lstatSync(e).isFile()}isEmptyDirectory(e){return!!this.isDirectory(e)&&0===this.getFiles(e).length}makeDirectory(e){s.mkdirSync(e,{recursive:!0})}write(e,t){s.existsSync(i.dirname(e))||s.mkdirSync(i.dirname(e),{recursive:!0}),s.writeFileSync(e,t)}});var p=n.facade(new class{constructor(){d.default(this,"renderInfo",r.hex("#00ffff")),d.default(this,"renderSuccess",r.hex("#00ff00")),d.default(this,"renderError",r.hex("#ff0000"))}async animate(e,t){var n=this;const s=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";const s=n.renderInfo(n.renderMarkdown(e)+".".repeat(i%4))+t;n.stdout(s)};let i=0;s();const r=setInterval((()=>(i++,s())),1e3),o=await t();return clearInterval(r),s("\n"),o}info(e){this.log(this.renderMarkdown(e),this.renderInfo)}error(e){this.log(this.renderMarkdown(e),this.renderError)}fail(e){this.error(e),process.exit(1)}success(e){this.log(this.renderMarkdown(e),this.renderSuccess)}renderMarkdown(e){const t=n.stringMatchAll(e,/\*\*(.*)\*\*/g);for(const n of t)e=e.replace(n[0],r.bold(n[1]));return e}log(e,t){this.formatMessage(e).forEach((e=>{this.logLine(t?t(e):e)}))}formatMessage(e){if("\n"===e[0]){const t=(e=e.slice(1).trimEnd()).split("\n"),n=e.trim()[0]??"",s=t.find((e=>e.trim().length>0))?.indexOf(n)??0;return t.map((e=>e.slice(s)))}return[e]}logLine(e){console.log(e)}stdout(e){o.cursorTo(process.stdout,0),o.clearLine(process.stdout,0),process.stdout.write(e)}});class h{static instantiate(e,t,n){return new h(e).instantiate(t,n)}constructor(e){d.default(this,"path",void 0),this.path=e}instantiate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=this.getFilenameReplacements(t),i=[];e=`${e}/`.replace(/\/\//,"/");for(const r of u.getFiles(this.path)){const o=Object.entries(n).reduce(((e,t)=>{let[n,s]=t;return e.replaceAll(n,s)}),r.substring(this.path.length+1)),l=s.readFileSync(r).toString(),c=e+(o.endsWith(".template")?o.slice(0,-9):o);u.write(c,a.render(l,t,void 0,["<%","%>"])),i.push(c)}return i}getFilenameReplacements(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return Object.entries(e).reduce(((e,s)=>{let[i,r]=s;return"object"==typeof r?Object.assign(e,this.getFilenameReplacements(r,`${i}.`)):e[`[${t}${i}]`]=n.toString(r),e}),{})}}function m(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return i.resolve(__dirname,"../",e)}function f(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=e.split("\n"),s=t.indent??0;let i=0,r="";for(const e of n){const t=e.trim(),n=0===t.length;if(0===r.length){if(n)continue;i=e.indexOf(t[0]??""),r+=`${" ".repeat(s)}${t}\n`;continue}if(n){r+="\n";continue}const o=e.indexOf(t[0]??"");r+=`${" ".repeat(s+o-i)}${t}\n`}return r.trimEnd()}class g{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};d.default(this,"name",void 0),d.default(this,"options",void 0),this.name=e,this.options=t}create(e){!u.exists(e)||u.isDirectory(e)&&u.isEmptyDirectory(e)||p.fail(`Folder at '${e}' already exists!`),h.instantiate(m("templates/app"),e,{app:{name:this.name,slug:n.stringToSlug(this.name)},local:this.options.local&&{aerogelPath:m("../")}})}}class y{static define(e){var t=this;e=e.command(this.command).description(this.description);for(const[t,n]of this.parameters)e=e.argument(`<${t}>`,n);for(const[t,n]of Object.entries(this.options)){const s="string"==typeof n?n:n.description,i="string"==typeof n?"string":n.type??"string";e=e.option("boolean"===i?`--${t}`:`--${t} <${i}>`,s)}e=e.action((function(){for(var e=arguments.length,n=new Array(e),s=0;s<e;s++)n[s]=arguments[s];return t.run.call(t,...n)}))}static async run(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];const s=new this(...t);await s.run()}async run(){}assertAerogelOrDirectory(e){const t=u.read("package.json");if(t?.includes("@aerogel/core"))return;if(e&&u.isDirectory(e))return;const n=e?`${e} folder does not exist.`:"package.json does not contain @aerogel/core.";p.fail(`${n} Are you sure this is an Aerogel app?`)}}d.default(y,"command",""),d.default(y,"description",""),d.default(y,"parameters",[]),d.default(y,"options",{});var w=n.facade(new class{constructor(){d.default(this,"cwd",null)}setWorkingDirectory(e){this.cwd=e}async run(e){await new Promise(((t,n)=>{l.exec(e,{cwd:this.cwd??void 0},(e=>{e?n(e):t()}))}))}});class v extends y{constructor(e,t){super(),d.default(this,"path",void 0),d.default(this,"options",void 0),this.path=e,this.options=t}async run(){const e=this.path,t=this.options.name??"Aerogel App";w.setWorkingDirectory(e),await this.createApp(t,e),await this.installDependencies(),await this.initializeGit(),p.success(`\n\n That's it! You can start working on **${t}** doing the following:\n\n cd ${e}\n npm run dev\n\n Have fun!\n `)}async createApp(e,t){p.info(`Creating **${e}**...`),new g(e,{local:this.options.local}).create(t)}async installDependencies(){await p.animate("Installing dependencies",(async()=>{await w.run("npm install")}))}async initializeGit(){await p.animate("Initializing git",(async()=>{await w.run("git init"),await w.run("git add ."),await w.run('git commit -m "Start"')}))}}d.default(v,"command","create"),d.default(v,"description","Create AerogelJS app"),d.default(v,"parameters",[["path","Application path"]]),d.default(v,"options",{name:"Application name",local:{type:"boolean",description:"Whether to create an app linked to local Aerogel packages (used for core development)"}});class x extends y{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),d.default(this,"path",void 0),d.default(this,"options",void 0),this.path=e,this.options=t}async run(){this.assertAerogelOrDirectory("src/components"),this.options.story&&this.assertHistoireInstalled(),u.exists(`src/components/${this.path}.vue`)&&p.fail(`${this.path} component already exists!`);const[e,t]=this.parsePathComponents(),n=h.instantiate(m("templates/component"),`src/components/${e}`,{component:{name:t}});if(this.options.story){const e=h.instantiate(m("templates/component-story"),"src/components",{component:{name:t}});n.push(...e)}const s=n.map((e=>`- ${e}`)).join("\n");p.info(`${t} component created successfully! The following files were created:\n\n${s}`)}assertHistoireInstalled(){u.exists("src/main.histoire.ts")||p.fail("Histoire is not installed yet!")}parsePathComponents(){const e=this.path.lastIndexOf("/");return-1===e?["",this.path]:[this.path.substring(0,e),this.path.substring(e+1)]}}d.default(x,"command","generate:component"),d.default(x,"description","Generate an AerogelJS component"),d.default(x,"parameters",[["path","Component path (relative to components folder; extension not necessary)"]]),d.default(x,"options",{story:{description:"Create component story using Histoire",type:"boolean"}});class $ extends y{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),d.default(this,"name",void 0),d.default(this,"options",void 0),this.name=e,this.options=t}async run(){this.assertAerogelOrDirectory("src/models"),u.exists(`src/models/${this.name}.ts`)&&p.fail(`${this.name} model already exists!`),this.assertSoukaiInstalled();const e=h.instantiate(m("templates/model"),"src/models",{model:{name:this.name,fieldsDefinition:this.getFieldsDefinition()},soukaiImports:this.options.fields?"FieldType, defineModelSchema":"defineModelSchema"}).map((e=>`- ${e}`)).join("\n");p.info(`${this.name} model created successfully! The following files were created:\n\n${e}`)}getFieldsDefinition(){if(!this.options.fields)return" //";const e=this.options.fields.split(",").map((e=>{const[t,s,i]=e.split(":");return{name:t,type:n.stringToStudlyCase(s??"string"),required:"required"===i}})).reduce(((e,t)=>e+`\n${t.required?f(`\n ${t.name}: {\n type: FieldType.${t.type},\n required: true,\n }\n `):`${t.name}: FieldType.${t.type}`},`),"");return f(e,{indent:8})}assertSoukaiInstalled(){u.contains("package.json",'"soukai"')||u.contains("package.json",'"@aerogel/plugin-soukai"')||p.fail("\n Soukai is not installed yet! You can install it doing the following:\n\n 1. Run the following command:\n npm install soukai @aerogel/plugin-soukai@next\n\n 2. Add this to your plugins array in src/main.ts:\n soukai({ models: import.meta.glob('@/models/*', { eager: true }) })\n ")}}d.default($,"command","generate:model"),d.default($,"description","Generate an AerogelJS model"),d.default($,"parameters",[["name","Model name"]]),d.default($,"options",{fields:"Create model with the given fields"});var j=n.facade(new class{run(t){const n=new e.Command;n.name("ag").description("AerogelJS CLI").version("0.0.0"),v.define(n),x.define(n),$.define(n),n.parse(t)}});exports.CLI=j;
|
|
2
|
-
//# sourceMappingURL=aerogel-cli.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aerogel-cli.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/aerogel-cli.esm.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{Command as e}from"commander";import t from"@babel/runtime/helpers/esm/defineProperty";import{facade as s,stringMatchAll as n,toString as i,stringToSlug as o,stringToStudlyCase as r}from"@noeldemartin/utils";import{existsSync as a,readFileSync as c,readdirSync as l,lstatSync as p,mkdirSync as d,writeFileSync as m}from"fs";import{resolve as h,dirname as u}from"path";import"core-js/modules/esnext.async-iterator.for-each.js";import"core-js/modules/esnext.iterator.constructor.js";import"core-js/modules/esnext.iterator.for-each.js";import"core-js/modules/esnext.async-iterator.find.js";import"core-js/modules/esnext.iterator.find.js";import"core-js/modules/esnext.async-iterator.map.js";import"core-js/modules/esnext.iterator.map.js";import{hex as f,bold as g}from"chalk";import{cursorTo as y,clearLine as w}from"readline";import"core-js/modules/esnext.async-iterator.reduce.js";import"core-js/modules/esnext.iterator.reduce.js";import{render as v}from"mustache";import{exec as $}from"child_process";var x=s(new class{contains(e,t){return!!this.read(e)?.includes(t)}exists(e){return a(e)}read(e){return this.isFile(e)?c(e).toString():null}getFiles(e){const t=l(e,{withFileTypes:!0}),s=[];for(const n of t){const t=h(e,n.name);n.isDirectory()?s.push(...this.getFiles(t)):s.push(t)}return s}isDirectory(e){return this.exists(e)&&p(e).isDirectory()}isFile(e){return this.exists(e)&&p(e).isFile()}isEmptyDirectory(e){return!!this.isDirectory(e)&&0===this.getFiles(e).length}makeDirectory(e){d(e,{recursive:!0})}write(e,t){a(u(e))||d(u(e),{recursive:!0}),m(e,t)}});var j=s(new class{constructor(){t(this,"renderInfo",f("#00ffff")),t(this,"renderSuccess",f("#00ff00")),t(this,"renderError",f("#ff0000"))}async animate(e,t){var s=this;const n=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";const n=s.renderInfo(s.renderMarkdown(e)+".".repeat(i%4))+t;s.stdout(n)};let i=0;n();const o=setInterval((()=>(i++,n())),1e3),r=await t();return clearInterval(o),n("\n"),r}info(e){this.log(this.renderMarkdown(e),this.renderInfo)}error(e){this.log(this.renderMarkdown(e),this.renderError)}fail(e){this.error(e),process.exit(1)}success(e){this.log(this.renderMarkdown(e),this.renderSuccess)}renderMarkdown(e){const t=n(e,/\*\*(.*)\*\*/g);for(const s of t)e=e.replace(s[0],g(s[1]));return e}log(e,t){this.formatMessage(e).forEach((e=>{this.logLine(t?t(e):e)}))}formatMessage(e){if("\n"===e[0]){const t=(e=e.slice(1).trimEnd()).split("\n"),s=e.trim()[0]??"",n=t.find((e=>e.trim().length>0))?.indexOf(s)??0;return t.map((e=>e.slice(n)))}return[e]}logLine(e){console.log(e)}stdout(e){y(process.stdout,0),w(process.stdout,0),process.stdout.write(e)}});class k{static instantiate(e,t,s){return new k(e).instantiate(t,s)}constructor(e){t(this,"path",void 0),this.path=e}instantiate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=this.getFilenameReplacements(t),n=[];e=`${e}/`.replace(/\/\//,"/");for(const i of x.getFiles(this.path)){const o=Object.entries(s).reduce(((e,t)=>{let[s,n]=t;return e.replaceAll(s,n)}),i.substring(this.path.length+1)),r=c(i).toString(),a=e+(o.endsWith(".template")?o.slice(0,-9):o);x.write(a,v(r,t,void 0,["<%","%>"])),n.push(a)}return n}getFilenameReplacements(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return Object.entries(e).reduce(((e,s)=>{let[n,o]=s;return"object"==typeof o?Object.assign(e,this.getFilenameReplacements(o,`${n}.`)):e[`[${t}${n}]`]=i(o),e}),{})}}function A(){return h(__dirname,"../",arguments.length>0&&void 0!==arguments[0]?arguments[0]:"")}function D(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=e.split("\n"),n=t.indent??0;let i=0,o="";for(const e of s){const t=e.trim(),s=0===t.length;if(0===o.length){if(s)continue;i=e.indexOf(t[0]??""),o+=`${" ".repeat(n)}${t}\n`;continue}if(s){o+="\n";continue}const r=e.indexOf(t[0]??"");o+=`${" ".repeat(n+r-i)}${t}\n`}return o.trimEnd()}class F{constructor(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t(this,"name",void 0),t(this,"options",void 0),this.name=e,this.options=s}create(e){!x.exists(e)||x.isDirectory(e)&&x.isEmptyDirectory(e)||j.fail(`Folder at '${e}' already exists!`),k.instantiate(A("templates/app"),e,{app:{name:this.name,slug:o(this.name)},local:this.options.local&&{aerogelPath:A("../")}})}}class I{static define(e){var t=this;e=e.command(this.command).description(this.description);for(const[t,s]of this.parameters)e=e.argument(`<${t}>`,s);for(const[t,s]of Object.entries(this.options)){const n="string"==typeof s?s:s.description,i="string"==typeof s?"string":s.type??"string";e=e.option("boolean"===i?`--${t}`:`--${t} <${i}>`,n)}e=e.action((function(){for(var e=arguments.length,s=new Array(e),n=0;n<e;n++)s[n]=arguments[n];return t.run.call(t,...s)}))}static async run(){for(var e=arguments.length,t=new Array(e),s=0;s<e;s++)t[s]=arguments[s];const n=new this(...t);await n.run()}async run(){}assertAerogelOrDirectory(e){const t=x.read("package.json");if(t?.includes("@aerogel/core"))return;if(e&&x.isDirectory(e))return;const s=e?`${e} folder does not exist.`:"package.json does not contain @aerogel/core.";j.fail(`${s} Are you sure this is an Aerogel app?`)}}t(I,"command",""),t(I,"description",""),t(I,"parameters",[]),t(I,"options",{});var b=s(new class{constructor(){t(this,"cwd",null)}setWorkingDirectory(e){this.cwd=e}async run(e){await new Promise(((t,s)=>{$(e,{cwd:this.cwd??void 0},(e=>{e?s(e):t()}))}))}});class S extends I{constructor(e,s){super(),t(this,"path",void 0),t(this,"options",void 0),this.path=e,this.options=s}async run(){const e=this.path,t=this.options.name??"Aerogel App";b.setWorkingDirectory(e),await this.createApp(t,e),await this.installDependencies(),await this.initializeGit(),j.success(`\n\n That's it! You can start working on **${t}** doing the following:\n\n cd ${e}\n npm run dev\n\n Have fun!\n `)}async createApp(e,t){j.info(`Creating **${e}**...`),new F(e,{local:this.options.local}).create(t)}async installDependencies(){await j.animate("Installing dependencies",(async()=>{await b.run("npm install")}))}async initializeGit(){await j.animate("Initializing git",(async()=>{await b.run("git init"),await b.run("git add ."),await b.run('git commit -m "Start"')}))}}t(S,"command","create"),t(S,"description","Create AerogelJS app"),t(S,"parameters",[["path","Application path"]]),t(S,"options",{name:"Application name",local:{type:"boolean",description:"Whether to create an app linked to local Aerogel packages (used for core development)"}});class O extends I{constructor(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"path",void 0),t(this,"options",void 0),this.path=e,this.options=s}async run(){this.assertAerogelOrDirectory("src/components"),this.options.story&&this.assertHistoireInstalled(),x.exists(`src/components/${this.path}.vue`)&&j.fail(`${this.path} component already exists!`);const[e,t]=this.parsePathComponents(),s=k.instantiate(A("templates/component"),`src/components/${e}`,{component:{name:t}});if(this.options.story){const e=k.instantiate(A("templates/component-story"),"src/components",{component:{name:t}});s.push(...e)}const n=s.map((e=>`- ${e}`)).join("\n");j.info(`${t} component created successfully! The following files were created:\n\n${n}`)}assertHistoireInstalled(){x.exists("src/main.histoire.ts")||j.fail("Histoire is not installed yet!")}parsePathComponents(){const e=this.path.lastIndexOf("/");return-1===e?["",this.path]:[this.path.substring(0,e),this.path.substring(e+1)]}}t(O,"command","generate:component"),t(O,"description","Generate an AerogelJS component"),t(O,"parameters",[["path","Component path (relative to components folder; extension not necessary)"]]),t(O,"options",{story:{description:"Create component story using Histoire",type:"boolean"}});class C extends I{constructor(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"name",void 0),t(this,"options",void 0),this.name=e,this.options=s}async run(){this.assertAerogelOrDirectory("src/models"),x.exists(`src/models/${this.name}.ts`)&&j.fail(`${this.name} model already exists!`),this.assertSoukaiInstalled();const e=k.instantiate(A("templates/model"),"src/models",{model:{name:this.name,fieldsDefinition:this.getFieldsDefinition()},soukaiImports:this.options.fields?"FieldType, defineModelSchema":"defineModelSchema"}).map((e=>`- ${e}`)).join("\n");j.info(`${this.name} model created successfully! The following files were created:\n\n${e}`)}getFieldsDefinition(){if(!this.options.fields)return" //";const e=this.options.fields.split(",").map((e=>{const[t,s,n]=e.split(":");return{name:t,type:r(s??"string"),required:"required"===n}})).reduce(((e,t)=>e+`\n${t.required?D(`\n ${t.name}: {\n type: FieldType.${t.type},\n required: true,\n }\n `):`${t.name}: FieldType.${t.type}`},`),"");return D(e,{indent:8})}assertSoukaiInstalled(){x.contains("package.json",'"soukai"')||x.contains("package.json",'"@aerogel/plugin-soukai"')||j.fail("\n Soukai is not installed yet! You can install it doing the following:\n\n 1. Run the following command:\n npm install soukai @aerogel/plugin-soukai@next\n\n 2. Add this to your plugins array in src/main.ts:\n soukai({ models: import.meta.glob('@/models/*', { eager: true }) })\n ")}}t(C,"command","generate:model"),t(C,"description","Generate an AerogelJS model"),t(C,"parameters",[["name","Model name"]]),t(C,"options",{fields:"Create model with the given fields"});var M=s(new class{run(t){const s=new e;s.name("ag").description("AerogelJS CLI").version("0.0.0"),S.define(s),O.define(s),C.define(s),s.parse(t)}});export{M as CLI};
|
|
2
|
-
//# sourceMappingURL=aerogel-cli.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aerogel-cli.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/noeldemartin.config.js
DELETED
package/src/lib/utils.test.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { formatCodeBlock } from './utils';
|
|
4
|
-
|
|
5
|
-
describe('Utils', () => {
|
|
6
|
-
|
|
7
|
-
it('Formats code blocks', () => {
|
|
8
|
-
// Arrange
|
|
9
|
-
const raw = `
|
|
10
|
-
|
|
11
|
-
const foo = 'bar';
|
|
12
|
-
|
|
13
|
-
if (foo) {
|
|
14
|
-
doSomething();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
`;
|
|
18
|
-
const formatted = [
|
|
19
|
-
'const foo = \'bar\';', //
|
|
20
|
-
'', //
|
|
21
|
-
'if (foo) {', //
|
|
22
|
-
' doSomething();', //
|
|
23
|
-
'}', //
|
|
24
|
-
].join('\n');
|
|
25
|
-
|
|
26
|
-
// Act
|
|
27
|
-
const actual = formatCodeBlock(raw);
|
|
28
|
-
|
|
29
|
-
// Assert
|
|
30
|
-
expect(actual).toEqual(formatted);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
});
|
package/src/lib/utils.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'path';
|
|
2
|
-
|
|
3
|
-
export interface FormatCodeBlockOptions {
|
|
4
|
-
indent?: number;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function basePath(path: string = ''): string {
|
|
8
|
-
return resolve(__dirname, '../', path);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function formatCodeBlock(code: string, options: FormatCodeBlockOptions = {}): string {
|
|
12
|
-
const lines = code.split('\n');
|
|
13
|
-
const indent = options.indent ?? 0;
|
|
14
|
-
let originalIndent = 0;
|
|
15
|
-
let formatted = '';
|
|
16
|
-
|
|
17
|
-
for (const line of lines) {
|
|
18
|
-
const trimmedLine = line.trim();
|
|
19
|
-
const isEmptyLine = trimmedLine.length === 0;
|
|
20
|
-
|
|
21
|
-
if (formatted.length === 0) {
|
|
22
|
-
if (isEmptyLine) {
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
originalIndent = line.indexOf(trimmedLine[0] ?? '');
|
|
27
|
-
formatted += `${' '.repeat(indent)}${trimmedLine}\n`;
|
|
28
|
-
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (isEmptyLine) {
|
|
33
|
-
formatted += '\n';
|
|
34
|
-
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const lineIndent = line.indexOf(trimmedLine[0] ?? '');
|
|
39
|
-
|
|
40
|
-
formatted += `${' '.repeat(indent + lineIndent - originalIndent)}${trimmedLine}\n`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return formatted.trimEnd();
|
|
44
|
-
}
|
package/tsconfig.json
DELETED
package/vite.config.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config';
|
|
2
|
-
import { resolve } from 'path';
|
|
3
|
-
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
test: {
|
|
6
|
-
clearMocks: true,
|
|
7
|
-
setupFiles: ['./src/testing/setup.ts'],
|
|
8
|
-
},
|
|
9
|
-
resolve: {
|
|
10
|
-
alias: {
|
|
11
|
-
'@': resolve(__dirname, './src'),
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
});
|
|
File without changes
|