cayo 0.9.10 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +504 -5
  2. package/cayo.js +1 -298
  3. package/devlog.md +177 -0
  4. package/dist/cayo.svelte.js +80 -0
  5. package/dist/entry.svelte.js +16 -0
  6. package/dist/index.js +2 -0
  7. package/docs/config-reference.md +349 -0
  8. package/docs/how-cayo-works.md +28 -0
  9. package/docs/why-i-created-cayo.md +21 -0
  10. package/lib/cli/build.js +34 -0
  11. package/lib/cli/cli.js +152 -0
  12. package/lib/cli/dev.js +12 -0
  13. package/lib/cli/serve.js +25 -0
  14. package/lib/cli/watch.js +125 -0
  15. package/lib/core/bundle.js +155 -0
  16. package/lib/core/codegen.js +156 -0
  17. package/lib/core/compile/cayos.js +65 -0
  18. package/lib/core/compile/index.js +3 -0
  19. package/lib/core/compile/pages.js +61 -0
  20. package/lib/core/compile/template.js +24 -0
  21. package/lib/core/component.js +62 -0
  22. package/lib/core/config.js +206 -0
  23. package/lib/core/dependencies.js +167 -0
  24. package/lib/core/entry.js +24 -0
  25. package/lib/core/files.js +99 -0
  26. package/lib/core/logger.js +47 -0
  27. package/lib/core/page.js +59 -0
  28. package/lib/core/render/prerender.js +240 -0
  29. package/lib/core/render/renderer.js +52 -0
  30. package/lib/core/utils.js +60 -0
  31. package/package.json +21 -10
  32. package/scripts/build.js +60 -0
  33. package/src/cayo-warnings.js +37 -0
  34. package/src/cayo.svelte +36 -0
  35. package/src/entry.svelte +6 -0
  36. package/template/cayo.config.js +3 -0
  37. package/template/package-lock.json +4027 -0
  38. package/template/package.json +10 -0
  39. package/template/public/vite.svg +1 -0
  40. package/{tests/basic cases (old)/src/__index.svelte → template/src/__template.svelte} +3 -6
  41. package/template/src/components/counter.cayo.svelte +27 -0
  42. package/template/src/index.js +4 -0
  43. package/template/src/pages/index.svelte +15 -0
  44. package/template/src/style.css +13 -0
  45. package/lib/cli.js +0 -69
  46. package/lib/codegen.js +0 -79
  47. package/lib/components/Cayo.svelte +0 -25
  48. package/lib/config.js +0 -155
  49. package/lib/files.js +0 -84
  50. package/lib/prerender.js +0 -181
  51. package/lib/renderer.js +0 -49
  52. package/lib/runtime.js +0 -6
  53. package/lib/utils.js +0 -126
  54. package/lib/vite.config.js +0 -16
  55. package/notes.md +0 -3
  56. package/test/cayo.config.js +0 -35
  57. package/test/public/assets/cow.js +0 -1
  58. package/test/public/images/app-icon.png +0 -0
  59. package/test/src/__layout.svelte +0 -20
  60. package/test/src/components/Cool.cayo.svelte +0 -5
  61. package/test/src/components/Some.svelte +0 -1
  62. package/test/src/components/Test.cayo.svelte +0 -5
  63. package/test/src/index.js +0 -17
  64. package/test/src/main2.js +0 -1
  65. package/test/src/pages/hey.svelte +0 -8
  66. package/test/src/pages/howdy.svelte +0 -11
  67. package/test/src/pages/index.svelte +0 -38
  68. package/test/src/pages/some/page.svelte +0 -2
  69. package/tests/asset-dir/cayo.config.js +0 -38
  70. package/tests/asset-dir/package-lock.json +0 -1435
  71. package/tests/asset-dir/package.json +0 -19
  72. package/tests/asset-dir/public/images/app-icon.png +0 -0
  73. package/tests/asset-dir/src/__layout.svelte +0 -20
  74. package/tests/asset-dir/src/components/CayoExample.svelte +0 -5
  75. package/tests/asset-dir/src/components/Some.cayo.svelte +0 -6
  76. package/tests/asset-dir/src/index.js +0 -5
  77. package/tests/asset-dir/src/pages/index.svelte +0 -19
  78. package/tests/base-path/cayo.config.js +0 -36
  79. package/tests/base-path/package-lock.json +0 -1435
  80. package/tests/base-path/package.json +0 -19
  81. package/tests/base-path/public/assets/cow.js +0 -1
  82. package/tests/base-path/public/images/app-icon.png +0 -0
  83. package/tests/base-path/src/__layout.svelte +0 -20
  84. package/tests/base-path/src/components/CayoExample.svelte +0 -5
  85. package/tests/base-path/src/components/Some.cayo.svelte +0 -6
  86. package/tests/base-path/src/index.js +0 -5
  87. package/tests/base-path/src/pages/howdy.svelte +0 -12
  88. package/tests/base-path/src/pages/index.svelte +0 -20
  89. package/tests/basic/notcayo.config.js +0 -35
  90. package/tests/basic/package-lock.json +0 -1435
  91. package/tests/basic/package.json +0 -19
  92. package/tests/basic/public/assets/cow.js +0 -1
  93. package/tests/basic/public/images/app-icon.png +0 -0
  94. package/tests/basic/src/__layout.svelte +0 -20
  95. package/tests/basic/src/components/Cool.cayo.svelte +0 -4
  96. package/tests/basic/src/components/Some.svelte +0 -1
  97. package/tests/basic/src/index.js +0 -5
  98. package/tests/basic/src/main2.js +0 -1
  99. package/tests/basic/src/pages/hey.svelte +0 -8
  100. package/tests/basic/src/pages/howdy.svelte +0 -11
  101. package/tests/basic/src/pages/index.svelte +0 -33
  102. package/tests/basic/src/pages/some/some.svelte +0 -2
  103. package/tests/basic cases (old)/src/components/Cool.cayo.svelte +0 -4
  104. package/tests/basic cases (old)/src/components/Some.svelte +0 -1
  105. package/tests/basic cases (old)/src/components/dir/Cool.cayo.svelte +0 -4
  106. package/tests/basic cases (old)/src/main.js +0 -1
  107. package/tests/basic cases (old)/src/main2.js +0 -1
  108. package/tests/basic cases (old)/src/pages/hey.svelte +0 -2
  109. package/tests/basic cases (old)/src/pages/howdy.svelte +0 -11
  110. package/tests/basic cases (old)/src/pages/index.svelte +0 -27
  111. package/tests/nested-pages/cayo.config.js +0 -35
  112. package/tests/nested-pages/package-lock.json +0 -1435
  113. package/tests/nested-pages/package.json +0 -19
  114. package/tests/nested-pages/public/assets/cow.js +0 -1
  115. package/tests/nested-pages/public/images/app-icon.png +0 -0
  116. package/tests/nested-pages/src/__layout.svelte +0 -20
  117. package/tests/nested-pages/src/components/Cool.cayo.svelte +0 -4
  118. package/tests/nested-pages/src/index.js +0 -5
  119. package/tests/nested-pages/src/main2.js +0 -1
  120. package/tests/nested-pages/src/pages/index.svelte +0 -18
  121. package/tests/nested-pages/src/pages/some/other/page.svelte +0 -7
  122. package/tests/nested-pages/src/pages/some/page.svelte +0 -6
@@ -0,0 +1,206 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import { z } from 'zod';
4
+ import merge from 'deepmerge';
5
+ import { defineConfig } from 'vite';
6
+ import { normalizePath } from './utils.js';
7
+
8
+ export async function validateConfig(userConfig) {
9
+ const ConfigSchema = z.object({
10
+ projectRoot: z
11
+ .string()
12
+ .default('.'),
13
+ src: z
14
+ .string()
15
+ .default('./src'),
16
+ pages: z
17
+ .string()
18
+ .default('./pages'),
19
+ components: z
20
+ .string()
21
+ .default('./components'),
22
+ publicDir: z
23
+ .string()
24
+ .default('./public'),
25
+ // TODO: make this an object with `value` and `mode` so it can be toggled per env if needed
26
+ base: z
27
+ .string()
28
+ .default('/'),
29
+ build: z
30
+ .object({
31
+ outDir: z
32
+ .string()
33
+ .default('./dist'),
34
+ assetsDir: z
35
+ .string()
36
+ .default('assets'),
37
+ })
38
+ .optional()
39
+ .default({}),
40
+ css: z
41
+ .object({
42
+ internal: z
43
+ .boolean()
44
+ .default(false),
45
+ })
46
+ .optional()
47
+ .default({}),
48
+ // Note: explicitly only supports these svelte config options
49
+ svelte: z.object({
50
+ preprocess: z.any().default([]),
51
+ compilerOptions: z.any().default({}),
52
+ extensions: z.string().array().default(['.svelte']),
53
+ }).default({}),
54
+ // Note: allows all vite config options
55
+ vite: z.any({}).default({
56
+ clearScreen: false,
57
+ rollupOptions: {
58
+ plugins: [],
59
+ },
60
+ }),
61
+ cayoPath: z
62
+ .string()
63
+ .default('.cayo/'),
64
+ cayoComponentInfix: z
65
+ .string()
66
+ .default('cayo'),
67
+ templateName: z
68
+ .string()
69
+ .default('__template'),
70
+ //TODO: make sure this matches the config docs
71
+ mode: z
72
+ .string()
73
+ .default('development'),
74
+ debug: z
75
+ .boolean()
76
+ .default(false),
77
+ });
78
+
79
+ return await ConfigSchema.strict().parseAsync(userConfig);
80
+ }
81
+
82
+ async function handlePaths(config, input, base) {
83
+ // Build paths from the config options
84
+ let projectRoot = normalizePath(base, config.projectRoot);
85
+ let src = normalizePath(projectRoot, config.src);
86
+ let pages = normalizePath(src, config.pages);
87
+ let components = normalizePath(src, config.components);
88
+ let publicDir = normalizePath(projectRoot, config.publicDir);
89
+ let build = {
90
+ outDir: normalizePath(projectRoot, config.build.outDir),
91
+ };
92
+
93
+
94
+ // Handle the template path a little differently below, since the option is a name not a path
95
+ let templateName = config.templateName;
96
+ let templatePath = path.join(src, `${templateName}.svelte`);
97
+
98
+ // Validate the built paths
99
+ let errorMessage = '';
100
+ let isError = false;
101
+ let isInvalidInput = false;
102
+ const pathsToCheck = { projectRoot, src, pages, components, templatePath, publicDir };
103
+ const exists = async (key, value) => {
104
+ if (!(await fs.pathExists(value))) {
105
+ if (!input[key] && key !== 'templatePath') {
106
+ errorMessage += `\n\n> Expected '${key}' path does not exist: ${value}`;
107
+ } else {
108
+ switch(key) {
109
+ case 'templatePath':
110
+ errorMessage += `\n\n> 'templateName': ${templateName} (.svelte) not found at root of 'src' path.`;
111
+ errorMessage += `\n Expected template path does not exist: ${templatePath}`;
112
+ break;
113
+ default:
114
+ errorMessage += `\n\n> ${key}: realtive path does not exist: ${input[key]}`
115
+ errorMessage += `\n Expected '${key}' path does not exist: ${value}`;
116
+ isInvalidInput = true;
117
+ }
118
+ }
119
+ isError = true;
120
+ }
121
+ }
122
+ for (const [key, value] of Object.entries(pathsToCheck)) {
123
+ exists(key, value);
124
+ }
125
+
126
+ if (!isError) {
127
+ // Update the config to use the validated absolute path values
128
+ config.projectRoot = projectRoot;
129
+ config.src = src;
130
+ config.pages = pages;
131
+ config.components = components;
132
+ config.template = templatePath;
133
+ config.publicDir = publicDir;
134
+ config.build.outDir = build.outDir;
135
+
136
+ } else {
137
+ if (isInvalidInput) errorMessage = 'Config includes an invalid path.' + errorMessage;
138
+ else errorMessage = `Project structure is invalid.` + errorMessage;
139
+ throw new Error(errorMessage);
140
+ }
141
+ }
142
+
143
+ function handleZodError(error) {
144
+ let msg = 'Config is invalid.';
145
+ for (const e of error.issues) {
146
+ msg += `\n\n> ${e.message}`;
147
+ }
148
+ throw new Error(msg);
149
+ }
150
+
151
+ export async function loadConfig(options) {
152
+ const configFileName = 'cayo.config.js';
153
+
154
+ // Use command-line options if user passes them
155
+ const root = options.projectRoot
156
+ ? path.resolve(options.projectRoot)
157
+ : process.cwd();
158
+
159
+ const configPath = options.configPath
160
+ ? path.resolve(root, options.configPath)
161
+ : path.resolve(root, `./${configFileName}`);
162
+
163
+ // Load config from user config file
164
+ let userConfig = { projectRoot: root, mode: options.mode };
165
+ if (fs.existsSync(configPath)) {
166
+ userConfig = {
167
+ ...(await import(configPath)).default,
168
+ ...userConfig,
169
+ };
170
+ }
171
+
172
+ let config = null;
173
+ try {
174
+ config = await validateConfig(userConfig);
175
+ await handlePaths(config, userConfig, root);
176
+ } catch (err) {
177
+ if (err instanceof z.ZodError) {
178
+ throw handleZodError(err);
179
+ }
180
+ throw err;
181
+ }
182
+
183
+ if (config && config.vite) {
184
+ const mergedViteConfig = merge(defineConfig({}), config.vite, { arrayMerge: combineMerge });
185
+ config.vite = mergedViteConfig;
186
+ }
187
+
188
+ return config;
189
+ }
190
+
191
+ // Credit: https://github.com/TehShrike/deepmerge#arraymerge-example-combine-arrays
192
+ function combineMerge(target, source, options) {
193
+ const destination = target.slice();
194
+
195
+ source.forEach((item, index) => {
196
+ if (typeof destination[index] === 'undefined') {
197
+ destination[index] = options.cloneUnlessOtherwiseSpecified(item, options);
198
+ } else if (options.isMergeableObject(item)) {
199
+ destination[index] = merge(target[index], item, options);
200
+ } else if (target.indexOf(item) === -1) {
201
+ destination.push(item);
202
+ }
203
+ });
204
+
205
+ return destination;
206
+ }
@@ -0,0 +1,167 @@
1
+ import path from 'path';
2
+ import precinct from 'precinct';
3
+ import { getDeps } from './bundle.js';
4
+
5
+ /**
6
+ * Adds dependencies to the dependency tree
7
+ *
8
+ * @param {object} depender – a dependency branch (for a page or child component)
9
+ * @param {object} dependencies – the dependency tree
10
+ */
11
+ function addDependencies(depender, dependencies) {
12
+ let type;
13
+ let branch = [...depender.dependencies];
14
+
15
+ // Update existing branches with these new deps where applicable
16
+ for (const [key, page] of Object.entries(dependencies.pages)) {
17
+ for (const component of dependencies.pages[key]) {
18
+ if (depender.path === component && dependencies.components[component]) {
19
+ dependencies.pages[key] = new Set([
20
+ ...dependencies.pages[key],
21
+ ...dependencies.components[component]
22
+ ]);
23
+ depender.dependencies = [...dependencies.pages[key]];
24
+ }
25
+ }
26
+ }
27
+
28
+ switch (depender.type) {
29
+ case 'page':
30
+ type = 'pages';
31
+ break;
32
+ case 'component':
33
+ type = 'components';
34
+ break;
35
+ case 'entry':
36
+ type = 'entries';
37
+ break;
38
+ case 'asset':
39
+ default:
40
+ type = 'assets';
41
+ break;
42
+ }
43
+
44
+ dependencies[type][depender.path] = new Set([...branch]);
45
+ }
46
+
47
+ /**
48
+ * Recursively handles component deps,
49
+ * updates the depedendency tree,
50
+ * and updates the list of compiled components
51
+ *
52
+ * @param {object} depender a dependency branch (for a page or child component)
53
+ * @param {object} stats information about all dependers, their dependencies,
54
+ * and what components have been compiled this run
55
+ * @param {object} config cayo config
56
+ */
57
+ export async function handleDependencies(depender, _cayo) {
58
+ const { stats, config } = _cayo;
59
+
60
+ // Add the depender to the dependency tree
61
+ const branch = addDependencies(depender, stats.dependencies);
62
+ // Add the depender to the list of compiled dependencies
63
+ stats.compiled.paths.add(depender.path);
64
+
65
+ // Iterate over the dependency tree
66
+ for (const dependency of depender.dependencies) {
67
+ let type;
68
+ if (dependency.endsWith('.svelte')) {
69
+ type = 'component';
70
+ } else if (dependency.endsWith('.js')) {
71
+ type = 'asset';
72
+ } else {
73
+ // Return early if it's not a file we can handle
74
+ return branch;
75
+ }
76
+
77
+ if (!stats.compiled.paths.has(dependency)) {
78
+ const deps = (await getDeps(dependency, config));
79
+ // Recursively handle nested dependencies
80
+ if (deps) {
81
+ await handleDependencies({
82
+ type,
83
+ path: dependency,
84
+ dependencies: deps
85
+ }, _cayo, config);
86
+ }
87
+ }
88
+ }
89
+
90
+ return branch;
91
+ }
92
+
93
+ export function findDependentPages(dependency, _cayo) {
94
+ const { components, pages } = _cayo.stats.dependencies;
95
+ const dependentComponents = new Set([dependency]);
96
+ const dependentPages = new Set();
97
+
98
+ // Lookup dependency in other components
99
+ for (const [depender, deps] of Object.entries(components)) {
100
+ if (deps.has(dependency)) {
101
+ dependentComponents.add(depender);
102
+ }
103
+ }
104
+
105
+ // Lookup any dependent components in pages
106
+ for (const [depender, deps] of Object.entries(pages)) {
107
+ for (const component of dependentComponents) {
108
+ if (deps.has(component)) {
109
+ dependentPages.add(depender)
110
+ }
111
+ }
112
+ }
113
+
114
+ return dependentPages;
115
+ }
116
+
117
+ export function findDependentCayos(pageDependency, _cayo) {
118
+ const { components, pages } = _cayo.stats.dependencies;
119
+ const dependentComponents = new Set([]);
120
+ const cayos = new Set([]);
121
+
122
+ // Lookup dependency in the page
123
+ for (const dep of pages[pageDependency]) {
124
+ if (dep.endsWith('.cayo.svelte')) cayos.add(dep);
125
+ else if (dep.endsWith('.svelte')) dependentComponents.add(dep);
126
+ }
127
+
128
+ // Lookup dependency in components that the page is dependent on
129
+ for (const component of dependentComponents) {
130
+ for (const dep of components[component]) {
131
+ if (dep.endsWith('.cayo.svelte')) {
132
+ cayos.add(dep);
133
+ }
134
+ }
135
+ }
136
+
137
+ return cayos;
138
+ }
139
+
140
+ export async function getEntryDependencies(entry, page, _cayo) {
141
+ const { config } = _cayo;
142
+ let imports = precinct(entry.code, { type: 'es6' });
143
+ // Filter out public path ('/') and node_modules ('<package>')
144
+ let localDeps = imports.filter(d => d.startsWith('../') || d.startsWith('./'));
145
+ let absoluteDeps = localDeps.map(d => path.resolve(path.dirname(entry.path), d));
146
+ let srcRelativeLocalDeps = localDeps.map((d, i) => {
147
+ let pageCayoPath = path.resolve(config.cayoPath, page.url === '/' ? './' : page.url);
148
+ return path.relative(pageCayoPath, absoluteDeps[i]);
149
+ });
150
+
151
+ entry.dependencies = [];
152
+ for (let i = 0; i < localDeps.length; i++) {
153
+ entry.dependencies.push([localDeps[i], srcRelativeLocalDeps[i]]);
154
+ }
155
+
156
+ const depender = {
157
+ type: 'entry',
158
+ path: entry.path,
159
+ dependencies: absoluteDeps,
160
+ }
161
+
162
+ try {
163
+ await handleDependencies(depender, _cayo);
164
+ } catch (err) {
165
+ throw new Error(`Parsing dependencies of entry file '${entry.path}'`, { cause: err })
166
+ }
167
+ }
@@ -0,0 +1,24 @@
1
+ import fs from 'fs-extra';
2
+ import { getEntryDependencies } from './dependencies.js';
3
+ import { generateCayoRuntimeImport } from './codegen.js';
4
+
5
+ export async function processEntrySource(entry, page, _cayo) {
6
+ try {
7
+ entry.code = await fs.readFile(entry.path, { encoding: 'utf8' });
8
+ } catch (err) {
9
+ throw err;
10
+ }
11
+
12
+ let code = `${entry.code}`;
13
+ // Rewrite dependency imports
14
+ await getEntryDependencies(entry, page, _cayo);
15
+ for (const [relativeDep, srcRelativeDep] of entry.dependencies) {
16
+ code = code.replace(relativeDep, srcRelativeDep);
17
+ }
18
+ // Prepend cayo runtime import to entry source code
19
+ if (entry.renderCayos) {
20
+ code = generateCayoRuntimeImport() + code;
21
+ }
22
+
23
+ return code;
24
+ }
@@ -0,0 +1,99 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import chalk from 'chalk';
4
+ import { processEntrySource } from './entry.js';
5
+ import prettier from 'prettier';
6
+ // import logger from './logger.js';
7
+
8
+ const logger = {
9
+ log: {
10
+ info: () => {}
11
+ }
12
+ }
13
+
14
+ // Write file content for a page
15
+ export async function writePageFiles(page, _cayo) {
16
+ const { config } = _cayo;
17
+ const outDir = config.cayoPath;
18
+ const { html, css, js, cayoAssets } = page.result;
19
+ const htmlPath = page.url === '/' ? 'index.html' : `${page.url}/index.html`;
20
+ const prettyHtml = prettier.format(html, { parser: 'html'})
21
+
22
+ // Write HTML
23
+ await fs.outputFile(path.resolve(outDir, `${htmlPath}`), prettyHtml)
24
+ .then(() => logger.log.info(
25
+ chalk.green('page build ') + chalk.dim(`${page.name}`),
26
+ { timestamp: true })
27
+ );
28
+ // Write CSS
29
+ if (css.code !== '' && !config.css.internal) {
30
+ const cssPath = page.url === '/' ? 'index.css' : `${page.url}/index.css`;
31
+ await fs.outputFile(path.resolve(outDir, cssPath), css)
32
+ .then(() => logger.log.info(
33
+ chalk.green('css build ') + chalk.dim(`${page.name}`),
34
+ { timestamp: true })
35
+ );
36
+ }
37
+ // Write Cayo runtime JS
38
+ if (js.code !== '') {
39
+ let jsPath = page.url === '/' ? 'cayo-runtime.js' : `${page.url}/cayo-runtime.js`;
40
+ let content = '';
41
+ content += js.code;
42
+ await fs.outputFile(path.resolve(outDir, jsPath), content)
43
+ .then(() => logger.log.info(
44
+ chalk.green('cayo runtime build ') + chalk.dim(`${page.name}`),
45
+ { timestamp: true })
46
+ );
47
+ }
48
+ // Write Cayo CSS
49
+ for (const [name, cayo] of Object.entries(cayoAssets)) {
50
+ if (cayo.css.code !== '' && !config.css.internal) {
51
+ const cssPath = `${name}.css`;
52
+ await fs.outputFile(path.resolve(outDir, cssPath), cayo.css.code)
53
+ .then(() => logger.log.info(
54
+ chalk.green('css build ') + chalk.dim(`${cssPath}`),
55
+ { timestamp: true })
56
+ );
57
+ }
58
+ }
59
+
60
+ await writeEntryFile(page, _cayo);
61
+ }
62
+
63
+ export async function writeEntryFile(page, _cayo) {
64
+ const { config } = _cayo;
65
+ const { entry } = page.result;
66
+
67
+ if (entry.path) {
68
+ // Get the processed entry code
69
+ // TODO: should this happen here?
70
+ let code = await processEntrySource(entry, page, _cayo);
71
+ // Write the processed entry file
72
+ let entryOutputPath = page.url === '/' ? `./index.js` : `${page.url}/index.js`;
73
+ await fs.outputFile(path.resolve(config.cayoPath, entryOutputPath), code)
74
+ .then(() => logger.log.info(
75
+ chalk.green('entry build ') + chalk.dim(`${page.name}`),
76
+ { timestamp: true }
77
+ ))
78
+ .catch(err => console.error(err));
79
+ }
80
+ }
81
+
82
+ export async function writeTemplateCSS(css, _cayo) {
83
+ const { config } = _cayo;
84
+ const outDir = config.cayoPath;
85
+
86
+ if (css.code !== '' && !config.css.internal) {
87
+ const cssPath = `__index.css`;
88
+ await fs.outputFile(path.resolve(outDir, cssPath), css.code)
89
+ .then(() => logger.log.info(
90
+ chalk.green('css build ') + chalk.dim(`${config.templateFileName}`),
91
+ { timestamp: true })
92
+ );
93
+ }
94
+ }
95
+
96
+ export function cleanCayoPath(cayoPath) {
97
+ fs.removeSync(cayoPath);
98
+ fs.ensureDirSync(cayoPath);
99
+ }
@@ -0,0 +1,47 @@
1
+ import { createLogger } from 'vite';
2
+ import chalk from 'chalk';
3
+
4
+ export const infoLogger = createLogger('info', {
5
+ prefix: chalk.magenta.bold('[cayo]'),
6
+ // allowClearScreen: true,
7
+ });
8
+ export const errorLoggerVite = createLogger('error', {
9
+ prefix: chalk.red.bold('[cayo]'),
10
+ // allowClearScreen: true,
11
+ });
12
+
13
+ const errorLogger = (err) => {
14
+ let errorMessage = err;
15
+ // TODO: good reason to write a new logger that is
16
+ // globally initialized and passed in a runtime object,
17
+ // so this could have access to _cayo.config options
18
+ // Only really useful for dev
19
+ // if (err.stack) errorMessage = err.stack;
20
+ console.error(chalk.red.bold(`${errorMessage}`));
21
+
22
+ if (err.cause && !err.cause.cause) {
23
+ console.error(`${chalk.red.bold('> Cause:')} ${chalk.red.bold(err.cause)}`);
24
+ // console.error(err.cause.stack);
25
+ } else {
26
+ handleCause(err);
27
+ }
28
+ }
29
+
30
+ const handleCause = (err) => {
31
+ let prefix = chalk.red.bold('> Cause:');
32
+ if (err.cause) {
33
+ console.error(`${prefix} ${chalk.red.bold(err.cause)}`);
34
+ // console.error(err.cause.stack);
35
+ handleCause(err.cause);
36
+ } else {
37
+ // console.error(`${prefix} ${chalk.red.bold(err.stack)}`);
38
+ // console.error(err.stack);
39
+ }
40
+ }
41
+
42
+ const logger = {
43
+ log: infoLogger,
44
+ error: errorLogger,
45
+ }
46
+
47
+ export default logger;
@@ -0,0 +1,59 @@
1
+ import { Component } from "./component.js";
2
+ import { prerender } from "./render/prerender.js";
3
+
4
+ export class Page extends Component {
5
+ constructor(
6
+ code,
7
+ layout,
8
+ sourcePath,
9
+ modulePath,
10
+ dependencies,
11
+ config
12
+ ) {
13
+ super(null, code, sourcePath, modulePath, dependencies, config);
14
+ this._url = sourcePath.replace(config.pages, '').replace('.svelte', '');
15
+ this._name = sourcePath.split('/').pop().replace('.svelte', '');
16
+ this._modulePath = modulePath;
17
+ this._sourcePath = sourcePath;
18
+ this._layout = layout;
19
+ this._result;
20
+ this._cayoComponents = {};
21
+
22
+ if (this._url === 'index') this._url = '/';
23
+ }
24
+
25
+ async render(_cayo, options = {}) {
26
+ const { load = false } = options;
27
+ if (load) await this.load();
28
+ try {
29
+ this._result = await prerender(
30
+ this,
31
+ _cayo,
32
+ );
33
+ } catch (err) {
34
+ throw new Error(`Could not prerender page '${this._name}'`, { cause: err })
35
+ }
36
+
37
+ return this;
38
+ }
39
+
40
+ get layout() {
41
+ return this._layout;
42
+ }
43
+
44
+ get url() {
45
+ return this._url;
46
+ }
47
+
48
+ get result() {
49
+ return this._result;
50
+ }
51
+
52
+ get sourcePath() {
53
+ return this._sourcePath;
54
+ }
55
+
56
+ addCayoComponents(name, cayo) {
57
+ this._cayoComponents[name] = cayo;
58
+ }
59
+ }