@plitzi/sdk-shared 0.38.6 → 0.38.8
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/CHANGELOG.md +381 -0
- package/dist/authoring/declare.d.ts +1 -1
- package/dist/authoring/index.mjs +4 -4
- package/dist/authoring/paramSpec.d.ts +2 -1
- package/dist/authoring/paramSpec.mjs +20 -11
- package/dist/dataSource/globalSources.d.ts +34 -1
- package/dist/dataSource/globalSources.mjs +22 -2
- package/dist/dataSource/hooks/index.d.ts +2 -1
- package/dist/dataSource/hooks/index.mjs +2 -1
- package/dist/dataSource/hooks/useResolvedVariables.d.ts +12 -0
- package/dist/dataSource/hooks/useResolvedVariables.mjs +28 -0
- package/dist/dataSource/index.mjs +2 -1
- package/dist/dataSource/resolveVariables.d.ts +2 -2
- package/dist/devTools/chrome.d.ts +1 -1
- package/dist/flags/useFlagResolution.mjs +6 -6
- package/dist/helpers/canonicalJson.d.ts +6 -0
- package/dist/helpers/canonicalJson.mjs +5 -0
- package/dist/index.mjs +62 -58
- package/dist/network/spaceEvents.d.ts +31 -1
- package/dist/network/spaceEvents.mjs +150 -147
- package/dist/project/layout.d.ts +197 -0
- package/dist/project/layout.mjs +394 -0
- package/dist/project/paths.d.ts +84 -0
- package/dist/project/paths.mjs +4 -0
- package/dist/project/root.d.ts +24 -0
- package/dist/project/root.mjs +26 -0
- package/dist/queries/index.d.ts +12 -2
- package/dist/queries/index.mjs +27 -17
- package/dist/queries/serverQueries.d.ts +22 -0
- package/dist/queries/serverQueries.mjs +9 -0
- package/dist/queries/useServerQuery.d.ts +19 -0
- package/dist/queries/useServerQuery.mjs +21 -0
- package/dist/server/rsc/refreshRsc.d.ts +22 -10
- package/dist/server/rsc/refreshRsc.mjs +65 -53
- package/dist/server/rsc/useRscRefresh.d.ts +2 -1
- package/dist/server/rsc/useRscRefresh.mjs +1 -1
- package/dist/source/export.d.ts +2 -2
- package/dist/source/import.d.ts +1 -1
- package/dist/store/index.d.ts +45 -45
- package/dist/style/cssLayers.d.ts +1 -1
- package/dist/style/index.d.ts +3 -0
- package/dist/style/index.mjs +5 -2
- package/dist/style/keyframes.d.ts +39 -0
- package/dist/style/keyframes.mjs +41 -0
- package/dist/style/notifications.d.ts +34 -12
- package/dist/style/notifications.mjs +69 -32
- package/dist/style/styleConditions.d.ts +43 -0
- package/dist/style/styleConditions.mjs +29 -0
- package/dist/style/styleConstants.d.ts +3 -2
- package/dist/style/styleConstants.mjs +2 -0
- package/dist/style/stylePseudos.d.ts +40 -0
- package/dist/style/stylePseudos.mjs +109 -0
- package/dist/style/styleStates.d.ts +35 -8
- package/dist/style/styleStates.mjs +38 -15
- package/dist/style/styleTarget.d.ts +23 -0
- package/dist/style/styleTarget.mjs +35 -0
- package/dist/types/AuthTypes.d.ts +5 -0
- package/dist/types/CommonTypes.d.ts +12 -0
- package/dist/types/SchemaTypes.d.ts +2 -0
- package/dist/types/ServerTypes.d.ts +11 -4
- package/dist/types/StoreTypes.d.ts +5 -1
- package/dist/types/StyleTypes.d.ts +20 -2
- package/package.json +46 -2
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The project's layout held to what reads it: every folder the server builds, runs or serves from where the CLI puts
|
|
3
|
+
* it, each with the file it starts at. One check, said the same by the three that read the project — its server at
|
|
4
|
+
* boot (`serveProject`), its authoring (`projectAuthoring`: `npm run author` and the CLI's checks) and `plitzi doctor`,
|
|
5
|
+
* which makes the fixes that have one reading (`autofix`). Pure file system: what a file holds is never imported.
|
|
6
|
+
*
|
|
7
|
+
* An `error` is what keeps a part of the project from running — a plugin the server cannot build, code in a folder
|
|
8
|
+
* nothing reads, settings Node never loads — and stops the server and the authoring; a `warning` works, and should not
|
|
9
|
+
* stay.
|
|
10
|
+
*/
|
|
11
|
+
export type LayoutLevel = 'error' | 'warning';
|
|
12
|
+
/** Every finding of the layout check, by its code: how much it matters, and what it means in a line. */
|
|
13
|
+
export declare const PROJECT_LAYOUT_CODES: {
|
|
14
|
+
readonly 'plugin-entry-missing': {
|
|
15
|
+
readonly level: "error";
|
|
16
|
+
readonly means: "a folder of src/plugins/ with no index.ts (or index.tsx), which the server builds the plugin from";
|
|
17
|
+
};
|
|
18
|
+
readonly 'plugin-entry-ambiguous': {
|
|
19
|
+
readonly level: "error";
|
|
20
|
+
readonly means: "a folder of src/plugins/ with both index.ts and index.tsx: a plugin starts at one";
|
|
21
|
+
};
|
|
22
|
+
readonly 'entry-not-typescript': {
|
|
23
|
+
readonly level: "error";
|
|
24
|
+
readonly means: "an entry the server builds or runs written as JavaScript (index.js, .jsx, .mjs, .cjs): the project is TypeScript";
|
|
25
|
+
};
|
|
26
|
+
readonly 'plugin-name-invalid': {
|
|
27
|
+
readonly level: "error";
|
|
28
|
+
readonly means: "a folder of src/plugins/ whose name cannot be an element type: a letter, then letters and digits";
|
|
29
|
+
};
|
|
30
|
+
readonly 'plugin-type-taken': {
|
|
31
|
+
readonly level: "error";
|
|
32
|
+
readonly means: "two folders of src/plugins/ that are the same element type (StoryEditor and storyEditor)";
|
|
33
|
+
};
|
|
34
|
+
readonly 'plugin-shadowed': {
|
|
35
|
+
readonly level: "error";
|
|
36
|
+
readonly means: "a plugin both in src/plugins/ and, as it was built, in vendor/plugins/: the built one runs";
|
|
37
|
+
};
|
|
38
|
+
readonly 'plugin-functions-entry-missing': {
|
|
39
|
+
readonly level: "error";
|
|
40
|
+
readonly means: "a plugin’s functions/ with code and no index.ts, which its server half is built from";
|
|
41
|
+
};
|
|
42
|
+
readonly 'functions-entry-missing': {
|
|
43
|
+
readonly level: "error";
|
|
44
|
+
readonly means: "src/functions/ with code and no index.ts, which the project’s functions are built from";
|
|
45
|
+
};
|
|
46
|
+
readonly 'runtime-entry-missing': {
|
|
47
|
+
readonly level: "error";
|
|
48
|
+
readonly means: "src/runtime/ with code and no index.ts, which the space’s runtime starts at";
|
|
49
|
+
};
|
|
50
|
+
readonly 'space-entry-missing': {
|
|
51
|
+
readonly level: "error";
|
|
52
|
+
readonly means: "a space written in the project with no src/space/index.ts, which the server and npm run author import";
|
|
53
|
+
};
|
|
54
|
+
readonly 'space-default-export': {
|
|
55
|
+
readonly level: "error";
|
|
56
|
+
readonly means: "src/space/index.ts exporting the space by default, where it is imported by name: `space`";
|
|
57
|
+
};
|
|
58
|
+
readonly 'vendor-manifest-missing': {
|
|
59
|
+
readonly level: "error";
|
|
60
|
+
readonly means: "a built plugin (vendor/plugins/<type>/) with no plugin-manifest.json";
|
|
61
|
+
};
|
|
62
|
+
readonly 'vendor-manifest-invalid': {
|
|
63
|
+
readonly level: "error";
|
|
64
|
+
readonly means: "a built plugin’s plugin-manifest.json that is not a manifest";
|
|
65
|
+
};
|
|
66
|
+
readonly 'vendor-script-missing': {
|
|
67
|
+
readonly level: "error";
|
|
68
|
+
readonly means: "a built plugin’s manifest naming no script to run, or one that is not there";
|
|
69
|
+
};
|
|
70
|
+
readonly 'env-in-src': {
|
|
71
|
+
readonly level: "error";
|
|
72
|
+
readonly means: ".env inside src/: Node reads the project’s settings from the .env at its root";
|
|
73
|
+
};
|
|
74
|
+
readonly 'folder-misplaced': {
|
|
75
|
+
readonly level: "error";
|
|
76
|
+
readonly means: "code in a folder named like one the server reads (src/plugin/, plugins/ at the root): nothing reads it";
|
|
77
|
+
};
|
|
78
|
+
readonly 'folder-near-miss': {
|
|
79
|
+
readonly level: "warning";
|
|
80
|
+
readonly means: "a folder named like one the server reads (src/Data/, src/runtimes/), which nothing reads";
|
|
81
|
+
};
|
|
82
|
+
readonly 'plugin-declaration-missing': {
|
|
83
|
+
readonly level: "warning";
|
|
84
|
+
readonly means: "a plugin folder with no declaration.ts: the space’s use of the plugin is held to nothing";
|
|
85
|
+
};
|
|
86
|
+
readonly 'plugin-file-loose': {
|
|
87
|
+
readonly level: "warning";
|
|
88
|
+
readonly means: "a file directly in src/plugins/, where every plugin is a folder";
|
|
89
|
+
};
|
|
90
|
+
readonly 'data-not-json': {
|
|
91
|
+
readonly level: "warning";
|
|
92
|
+
readonly means: "a file of src/data/ that is not JSON, which no provider and no ctx.data reads";
|
|
93
|
+
};
|
|
94
|
+
readonly 'env-missing': {
|
|
95
|
+
readonly level: "warning";
|
|
96
|
+
readonly means: "no .env at the project’s root: none of its settings is set";
|
|
97
|
+
};
|
|
98
|
+
readonly 'env-example-missing': {
|
|
99
|
+
readonly level: "warning";
|
|
100
|
+
readonly means: "no .env.example: a clone does not know what .env must hold";
|
|
101
|
+
};
|
|
102
|
+
readonly 'public-data': {
|
|
103
|
+
readonly level: "warning";
|
|
104
|
+
readonly means: "JSON in public/data/ of a project with a server: served to anyone who asks";
|
|
105
|
+
};
|
|
106
|
+
readonly 'public-secret-file': {
|
|
107
|
+
readonly level: "warning";
|
|
108
|
+
readonly means: "a file in public/ named like a secret (.env, a key, a dump): served to anyone who asks";
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
export type LayoutCode = keyof typeof PROJECT_LAYOUT_CODES;
|
|
112
|
+
/**
|
|
113
|
+
* The fix of a finding that has one reading, for `plitzi doctor --fix` to make. Paths are relative to the root, a
|
|
114
|
+
* folder's ending in `/`: a `move` of a folder takes everything under it, into a folder that may already be there.
|
|
115
|
+
*/
|
|
116
|
+
export type LayoutAutofix = {
|
|
117
|
+
action: 'move';
|
|
118
|
+
from: string;
|
|
119
|
+
to: string;
|
|
120
|
+
} | {
|
|
121
|
+
action: 'copy';
|
|
122
|
+
from: string;
|
|
123
|
+
to: string;
|
|
124
|
+
} | {
|
|
125
|
+
action: 'write';
|
|
126
|
+
file: string;
|
|
127
|
+
contents: string;
|
|
128
|
+
};
|
|
129
|
+
/** One thing out of place: where (`file`, relative to the root), what is wrong, and what to do — the command, if any. */
|
|
130
|
+
export interface LayoutFinding {
|
|
131
|
+
level: LayoutLevel;
|
|
132
|
+
code: LayoutCode;
|
|
133
|
+
file: string;
|
|
134
|
+
message: string;
|
|
135
|
+
fix: string;
|
|
136
|
+
autofix?: LayoutAutofix;
|
|
137
|
+
}
|
|
138
|
+
export interface ProjectLayoutOptions {
|
|
139
|
+
/** Whether the project runs a server of its own — told by its `@plitzi/sdk-server` dependency when left out. */
|
|
140
|
+
mode?: 'server' | 'client';
|
|
141
|
+
/** Where its space is: written in it (`src/space/`), or kept on Plitzi — told by its files when left out. */
|
|
142
|
+
space?: 'local' | 'cloud';
|
|
143
|
+
}
|
|
144
|
+
/** `src/plugins/StatCard` is the plugin `statCard`: what the server registers a folder as. */
|
|
145
|
+
export declare const pluginTypeOf: (folder: string) => string;
|
|
146
|
+
/**
|
|
147
|
+
* The file an element's folder is built from, wherever the folder is — its `index.ts`, or `index.tsx` — or nothing
|
|
148
|
+
* when it has neither, or both: what `plitzi plugin pack` builds a folder from, as the server does.
|
|
149
|
+
*/
|
|
150
|
+
export declare const elementEntry: (dir: string) => string | undefined;
|
|
151
|
+
/**
|
|
152
|
+
* The file a folder of `src/plugins/` is built from (`elementEntry`) — or nothing when it is no plugin the server can
|
|
153
|
+
* build: a name that is no element type, no entry, or both. What the server registers, and what `checkPluginFolder`
|
|
154
|
+
* says why of.
|
|
155
|
+
*/
|
|
156
|
+
export declare const pluginEntry: (root: string, folder: string) => string | undefined;
|
|
157
|
+
/**
|
|
158
|
+
* One folder of `src/plugins/` as the server reads it: a name that is a type, the entry it is built from, its server
|
|
159
|
+
* half's entry, and its declaration. What the server says of a folder added while it runs, and what
|
|
160
|
+
* `checkProjectLayout` says of each.
|
|
161
|
+
*/
|
|
162
|
+
export declare const checkPluginFolder: (root: string, folder: string) => LayoutFinding[];
|
|
163
|
+
/** What a built plugin runs, by absolute path: its script, its style and its server half, as its manifest names them. */
|
|
164
|
+
export interface VendorPlugin {
|
|
165
|
+
script: string;
|
|
166
|
+
style?: string;
|
|
167
|
+
version: string;
|
|
168
|
+
functions?: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* A plugin of `vendor/plugins/` — one a project made from a space runs as it was built, beside the manifest `plitzi
|
|
172
|
+
* pack plugin` wrote when it was published — or what keeps it from running.
|
|
173
|
+
*/
|
|
174
|
+
export declare const readVendorPlugin: (root: string, type: string) => VendorPlugin | {
|
|
175
|
+
problem: LayoutFinding;
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Everything out of place in the project at `root`, errors first: what its server, its authoring and `plitzi doctor`
|
|
179
|
+
* say of its layout. `PROJECT_LAYOUT_CODES` says what each code means.
|
|
180
|
+
*/
|
|
181
|
+
export declare const checkProjectLayout: (root: string, options?: ProjectLayoutOptions) => LayoutFinding[];
|
|
182
|
+
/** One finding as the terminal says it: what is wrong, then what to do. */
|
|
183
|
+
export declare const layoutFindingText: (layoutFinding: LayoutFinding) => string;
|
|
184
|
+
/**
|
|
185
|
+
* The errors of a project's layout, every one at once: what its server and its authoring refuse to start with.
|
|
186
|
+
* `findings` holds them as data, for a tool that says them its own way.
|
|
187
|
+
*/
|
|
188
|
+
export declare class ProjectLayoutError extends Error {
|
|
189
|
+
#private;
|
|
190
|
+
get findings(): readonly LayoutFinding[];
|
|
191
|
+
constructor(findings: readonly LayoutFinding[]);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* The project's layout, refused with every error at once (`ProjectLayoutError`) — what its server and its authoring
|
|
195
|
+
* check before anything else — and its warnings answered, for the caller to say.
|
|
196
|
+
*/
|
|
197
|
+
export declare const assertProjectLayout: (root: string, options?: ProjectLayoutOptions) => LayoutFinding[];
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import { isRecord as e } from "../helpers/isRecord.mjs";
|
|
2
|
+
import { AUTHOR_FILE as t, DATA_DIR as n, FUNCTIONS_DIR as r, PLUGINS_DIR as i, PLUGIN_DECLARATION_FILE as a, PLUGIN_ENTRIES as o, PLUGIN_FUNCTIONS_DIR as s, PLUGIN_MANIFEST_FILE as c, PUBLIC_DIR as l, RUNTIME_DIR as u, SPACE_DIR as d, SPACE_ENTRY as f, VENDOR_PLUGINS_DIR as p } from "./paths.mjs";
|
|
3
|
+
import m from "node:path";
|
|
4
|
+
import { readFileSync as h, readdirSync as g, statSync as _ } from "node:fs";
|
|
5
|
+
//#region src/project/layout.ts
|
|
6
|
+
var v = {
|
|
7
|
+
"plugin-entry-missing": {
|
|
8
|
+
level: "error",
|
|
9
|
+
means: "a folder of src/plugins/ with no index.ts (or index.tsx), which the server builds the plugin from"
|
|
10
|
+
},
|
|
11
|
+
"plugin-entry-ambiguous": {
|
|
12
|
+
level: "error",
|
|
13
|
+
means: "a folder of src/plugins/ with both index.ts and index.tsx: a plugin starts at one"
|
|
14
|
+
},
|
|
15
|
+
"entry-not-typescript": {
|
|
16
|
+
level: "error",
|
|
17
|
+
means: "an entry the server builds or runs written as JavaScript (index.js, .jsx, .mjs, .cjs): the project is TypeScript"
|
|
18
|
+
},
|
|
19
|
+
"plugin-name-invalid": {
|
|
20
|
+
level: "error",
|
|
21
|
+
means: "a folder of src/plugins/ whose name cannot be an element type: a letter, then letters and digits"
|
|
22
|
+
},
|
|
23
|
+
"plugin-type-taken": {
|
|
24
|
+
level: "error",
|
|
25
|
+
means: "two folders of src/plugins/ that are the same element type (StoryEditor and storyEditor)"
|
|
26
|
+
},
|
|
27
|
+
"plugin-shadowed": {
|
|
28
|
+
level: "error",
|
|
29
|
+
means: "a plugin both in src/plugins/ and, as it was built, in vendor/plugins/: the built one runs"
|
|
30
|
+
},
|
|
31
|
+
"plugin-functions-entry-missing": {
|
|
32
|
+
level: "error",
|
|
33
|
+
means: "a plugin’s functions/ with code and no index.ts, which its server half is built from"
|
|
34
|
+
},
|
|
35
|
+
"functions-entry-missing": {
|
|
36
|
+
level: "error",
|
|
37
|
+
means: "src/functions/ with code and no index.ts, which the project’s functions are built from"
|
|
38
|
+
},
|
|
39
|
+
"runtime-entry-missing": {
|
|
40
|
+
level: "error",
|
|
41
|
+
means: "src/runtime/ with code and no index.ts, which the space’s runtime starts at"
|
|
42
|
+
},
|
|
43
|
+
"space-entry-missing": {
|
|
44
|
+
level: "error",
|
|
45
|
+
means: "a space written in the project with no src/space/index.ts, which the server and npm run author import"
|
|
46
|
+
},
|
|
47
|
+
"space-default-export": {
|
|
48
|
+
level: "error",
|
|
49
|
+
means: "src/space/index.ts exporting the space by default, where it is imported by name: `space`"
|
|
50
|
+
},
|
|
51
|
+
"vendor-manifest-missing": {
|
|
52
|
+
level: "error",
|
|
53
|
+
means: "a built plugin (vendor/plugins/<type>/) with no plugin-manifest.json"
|
|
54
|
+
},
|
|
55
|
+
"vendor-manifest-invalid": {
|
|
56
|
+
level: "error",
|
|
57
|
+
means: "a built plugin’s plugin-manifest.json that is not a manifest"
|
|
58
|
+
},
|
|
59
|
+
"vendor-script-missing": {
|
|
60
|
+
level: "error",
|
|
61
|
+
means: "a built plugin’s manifest naming no script to run, or one that is not there"
|
|
62
|
+
},
|
|
63
|
+
"env-in-src": {
|
|
64
|
+
level: "error",
|
|
65
|
+
means: ".env inside src/: Node reads the project’s settings from the .env at its root"
|
|
66
|
+
},
|
|
67
|
+
"folder-misplaced": {
|
|
68
|
+
level: "error",
|
|
69
|
+
means: "code in a folder named like one the server reads (src/plugin/, plugins/ at the root): nothing reads it"
|
|
70
|
+
},
|
|
71
|
+
"folder-near-miss": {
|
|
72
|
+
level: "warning",
|
|
73
|
+
means: "a folder named like one the server reads (src/Data/, src/runtimes/), which nothing reads"
|
|
74
|
+
},
|
|
75
|
+
"plugin-declaration-missing": {
|
|
76
|
+
level: "warning",
|
|
77
|
+
means: "a plugin folder with no declaration.ts: the space’s use of the plugin is held to nothing"
|
|
78
|
+
},
|
|
79
|
+
"plugin-file-loose": {
|
|
80
|
+
level: "warning",
|
|
81
|
+
means: "a file directly in src/plugins/, where every plugin is a folder"
|
|
82
|
+
},
|
|
83
|
+
"data-not-json": {
|
|
84
|
+
level: "warning",
|
|
85
|
+
means: "a file of src/data/ that is not JSON, which no provider and no ctx.data reads"
|
|
86
|
+
},
|
|
87
|
+
"env-missing": {
|
|
88
|
+
level: "warning",
|
|
89
|
+
means: "no .env at the project’s root: none of its settings is set"
|
|
90
|
+
},
|
|
91
|
+
"env-example-missing": {
|
|
92
|
+
level: "warning",
|
|
93
|
+
means: "no .env.example: a clone does not know what .env must hold"
|
|
94
|
+
},
|
|
95
|
+
"public-data": {
|
|
96
|
+
level: "warning",
|
|
97
|
+
means: "JSON in public/data/ of a project with a server: served to anyone who asks"
|
|
98
|
+
},
|
|
99
|
+
"public-secret-file": {
|
|
100
|
+
level: "warning",
|
|
101
|
+
means: "a file in public/ named like a secret (.env, a key, a dump): served to anyone who asks"
|
|
102
|
+
}
|
|
103
|
+
}, y = (e, t, n, r, i) => ({
|
|
104
|
+
level: v[e].level,
|
|
105
|
+
code: e,
|
|
106
|
+
file: t,
|
|
107
|
+
message: n,
|
|
108
|
+
fix: r,
|
|
109
|
+
...i ? { autofix: i } : {}
|
|
110
|
+
}), b = /* @__PURE__ */ new Set([
|
|
111
|
+
".gitkeep",
|
|
112
|
+
"README.md",
|
|
113
|
+
".DS_Store"
|
|
114
|
+
]), ee = /^index\.(?:js|jsx|mjs|cjs)$/, x = /^[A-Za-z][A-Za-z0-9]*$/, S = (e) => {
|
|
115
|
+
let t = {
|
|
116
|
+
files: [],
|
|
117
|
+
folders: []
|
|
118
|
+
};
|
|
119
|
+
try {
|
|
120
|
+
for (let n of g(e, { withFileTypes: !0 })) {
|
|
121
|
+
let r = n.isSymbolicLink() ? _(m.join(e, n.name), { throwIfNoEntry: !1 }) : void 0;
|
|
122
|
+
n.isFile() || r?.isFile() ? t.files.push(n.name) : (n.isDirectory() || r?.isDirectory()) && t.folders.push(n.name);
|
|
123
|
+
}
|
|
124
|
+
} catch {
|
|
125
|
+
return t;
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
files: t.files.sort(),
|
|
129
|
+
folders: t.folders.sort()
|
|
130
|
+
};
|
|
131
|
+
}, C = (e, t, n) => {
|
|
132
|
+
let r = t.split("/").filter((e) => e !== "" && e !== "."), i = e;
|
|
133
|
+
for (let [e, t] of r.entries()) {
|
|
134
|
+
let { files: a, folders: o } = S(i);
|
|
135
|
+
if (!(e === r.length - 1 && n === "file" ? a : o).includes(t)) return !1;
|
|
136
|
+
i = m.join(i, t);
|
|
137
|
+
}
|
|
138
|
+
return !0;
|
|
139
|
+
}, w = (e, t, n = /* @__PURE__ */ new Set()) => {
|
|
140
|
+
let { files: r, folders: i } = S(m.join(e, t));
|
|
141
|
+
return [...r.map((e) => `${t}/${e}`), ...i.filter((e) => !n.has(e)).flatMap((r) => w(e, `${t}/${r}`, n))];
|
|
142
|
+
}, T = ({ files: e, folders: t }) => t.length > 0 || e.some((e) => !b.has(e)), E = (e, t) => e.toLowerCase() === t.toLowerCase(), D = (e) => `${e.charAt(0).toUpperCase()}${e.slice(1)}`, O = (e, t) => {
|
|
143
|
+
let n = Array.from({ length: e.length + 1 }, (e, n) => Array.from({ length: t.length + 1 }, (e, t) => Math.max(n, t) * Number(n === 0 || t === 0)));
|
|
144
|
+
for (let r = 1; r <= e.length; r++) for (let i = 1; i <= t.length; i++) {
|
|
145
|
+
let a = e[r - 1] === t[i - 1] ? 0 : 1;
|
|
146
|
+
n[r][i] = Math.min(n[r - 1][i] + 1, n[r][i - 1] + 1, n[r - 1][i - 1] + a), r > 1 && i > 1 && e[r - 1] === t[i - 2] && e[r - 2] === t[i - 1] && (n[r][i] = Math.min(n[r][i], n[r - 2][i - 2] + 1));
|
|
147
|
+
}
|
|
148
|
+
return n[e.length][t.length];
|
|
149
|
+
}, k = (e, t) => {
|
|
150
|
+
if (e === t) return !1;
|
|
151
|
+
let n = e.toLowerCase(), r = t.toLowerCase();
|
|
152
|
+
return n === r || n === `${r}s` || `${n}s` === r || r.length >= 5 && O(n, r) <= 1;
|
|
153
|
+
}, A = "macOS and Windows disks ignore case, so it is found there — and not on Linux, where the project is deployed.", j = (e, t) => E(e, t) ? `git mv ${e} ${e}-tmp && git mv ${e}-tmp ${t}` : `git mv ${e} ${t}`, M = (e) => `${e.charAt(0).toLowerCase()}${e.slice(1)}`, N = (e) => {
|
|
154
|
+
let t = e.split(/[^A-Za-z0-9]+/).filter(Boolean).map(D).join(""), n = /^\d+/.exec(t)?.[0] ?? "", r = `${D(t.slice(n.length))}${n}`;
|
|
155
|
+
return x.test(r) ? r : void 0;
|
|
156
|
+
}, P = (e) => {
|
|
157
|
+
let { files: t } = S(e), n = o.filter((e) => t.includes(e));
|
|
158
|
+
return n.length === 1 ? m.join(e, n[0]) : void 0;
|
|
159
|
+
}, F = (e, t) => x.test(t) ? P(m.join(e, i, t)) : void 0, I = (e) => e.length > 1 ? `${e[0]} (or ${e.slice(1).join(", ")})` : e[0], L = (e, t) => {
|
|
160
|
+
let { folder: n, accepted: r, code: i, lost: a } = t, o = S(m.join(e, n)), s = r.filter((e) => o.files.includes(e));
|
|
161
|
+
if (s.length === 1) return [];
|
|
162
|
+
if (s.length > 1) return [y("plugin-entry-ambiguous", `${n}/`, `${n}/ has both ${s.join(" and ")}, and a plugin is built from one of them.`, `Keep one — ${s[s.length - 1]} when it writes JSX — and delete the other.`)];
|
|
163
|
+
let c = o.files.find((e) => ee.test(e));
|
|
164
|
+
if (c) {
|
|
165
|
+
let e = c.endsWith(".jsx") && r.includes("index.tsx") ? "index.tsx" : "index.ts";
|
|
166
|
+
return [y("entry-not-typescript", `${n}/${c}`, `${n}/${c} is JavaScript, and ${n}/ is built from ${I(r)}: the project's code is TypeScript, so ${a}.`, `Rename it ${e} — JavaScript is TypeScript already, types left out: ${j(`${n}/${c}`, `${n}/${e}`)}`, {
|
|
167
|
+
action: "move",
|
|
168
|
+
from: `${n}/${c}`,
|
|
169
|
+
to: `${n}/${e}`
|
|
170
|
+
})];
|
|
171
|
+
}
|
|
172
|
+
let l = o.files.find((e) => r.some((t) => k(e, t)));
|
|
173
|
+
if (l) {
|
|
174
|
+
let e = r.find((e) => k(l, e)) ?? r[0];
|
|
175
|
+
return [y(i, `${n}/${l}`, `${n}/ has no ${e} — did you mean ${l}? Named otherwise, ${a}.${E(l, e) ? ` ${A}` : ""}`, `Rename it ${e}: ${j(`${n}/${l}`, `${n}/${e}`)}`, {
|
|
176
|
+
action: "move",
|
|
177
|
+
from: `${n}/${l}`,
|
|
178
|
+
to: `${n}/${e}`
|
|
179
|
+
})];
|
|
180
|
+
}
|
|
181
|
+
let u = o.folders.find((t) => r.some((r) => C(e, `${n}/${t}/${r}`, "file")));
|
|
182
|
+
return u ? [y(i, `${n}/${u}/`, `${n}/ has no ${I(r)}, and ${n}/${u}/ has: one folder too deep, so ${a}.`, `Move what ${n}/${u}/ holds up into ${n}/.`, {
|
|
183
|
+
action: "move",
|
|
184
|
+
from: `${n}/${u}/`,
|
|
185
|
+
to: `${n}/`
|
|
186
|
+
})] : [y(i, `${n}/`, `${n}/ has no ${I(r)}, so ${a}.`, t.write)];
|
|
187
|
+
}, R = (e, t) => T(S(m.join(e, t.folder))) ? L(e, t) : [], te = (e) => {
|
|
188
|
+
let t = N(e), n = `${i}/${e}`;
|
|
189
|
+
return y("plugin-name-invalid", `${n}/`, `${n}/ cannot be a plugin: a folder of ${i}/ is registered as the element type its name makes, and a type is a letter followed by letters and digits.${t ? ` Did you mean ${t}?` : ""}`, t ? `Rename it ${t} — the type ${M(t)}: ${j(n, `${i}/${t}`)}; then type: '${M(t)}' in its ${a}, and renderType: '${M(t)}' where the space renders it.` : "Rename it with letters and digits, starting with a letter: StatCard is the type statCard.");
|
|
190
|
+
}, ne = (e, t) => e.find((e) => e === `${t}.tsx`) ?? e.find((e) => e === `${t}.ts`), z = (e, t) => {
|
|
191
|
+
let n = `${i}/${t}`, { files: r } = S(m.join(e, n));
|
|
192
|
+
if (r.includes("declaration.ts")) return [];
|
|
193
|
+
let o = M(t), s = `authoring holds none of the space's ${o} elements to its attributes, and the builder does not offer it`, c = r.find((e) => k(e, a));
|
|
194
|
+
return c ? [y("plugin-declaration-missing", `${n}/${c}`, `${n}/ has no ${a} — did you mean ${c}? Named otherwise, ${s}.${E(c, "declaration.ts") ? ` ${A}` : ""}`, `Rename it ${a}: ${j(`${n}/${c}`, `${n}/${a}`)}`, {
|
|
195
|
+
action: "move",
|
|
196
|
+
from: `${n}/${c}`,
|
|
197
|
+
to: `${n}/${a}`
|
|
198
|
+
})] : [y("plugin-declaration-missing", `${n}/`, `${n}/ has no ${a}: ${s}.`, `Write ${n}/${a} — export default { type: '${o}', … } — as npx plitzi plugin add writes one beside the component it makes.`)];
|
|
199
|
+
}, B = (e, t) => {
|
|
200
|
+
if (!x.test(t)) return [te(t)];
|
|
201
|
+
let n = `${i}/${t}`, r = M(t), a = ne(S(m.join(e, n)).files, t);
|
|
202
|
+
return [
|
|
203
|
+
...L(e, {
|
|
204
|
+
folder: n,
|
|
205
|
+
accepted: o,
|
|
206
|
+
code: "plugin-entry-missing",
|
|
207
|
+
lost: `the server cannot build the plugin ${r}`,
|
|
208
|
+
write: `Write ${n}/index.ts exporting the component by default${a ? ` — export { default } from './${a}';` : ""} — as npx plitzi plugin add writes it. Every folder of ${i}/ is a plugin: code several plugins share goes outside it (src/shared/).`
|
|
209
|
+
}),
|
|
210
|
+
...R(e, {
|
|
211
|
+
folder: `${n}/${s}`,
|
|
212
|
+
accepted: ["index.ts"],
|
|
213
|
+
code: "plugin-functions-entry-missing",
|
|
214
|
+
lost: `none of the plugin's server half runs (its routes under /fn/plugins/${r}/)`,
|
|
215
|
+
write: `Write ${n}/${s}/index.ts exporting defineFunctions({ … }) by default — as npx plitzi plugin add --server writes it.`
|
|
216
|
+
}),
|
|
217
|
+
...z(e, t)
|
|
218
|
+
];
|
|
219
|
+
}, V = (e) => {
|
|
220
|
+
let t = /* @__PURE__ */ new Map();
|
|
221
|
+
for (let n of e.filter((e) => x.test(e))) t.set(M(n), [...t.get(M(n)) ?? [], n]);
|
|
222
|
+
return [...t].flatMap(([e, t]) => t.slice(1).map((n) => y("plugin-type-taken", `${i}/${n}/`, `${i}/${t[0]}/ and ${i}/${n}/ are both the plugin ${e}: the server registers a folder by its name with a small first letter, and keeps one.`, `Put them in one folder, or rename one: git mv ${i}/${n} ${i}/<AnotherName>`)));
|
|
223
|
+
}, H = (t) => e(t.assets) ? Object.values(t.assets).flatMap((t) => e(t) && typeof t.src == "string" && typeof t.type == "string" ? [{
|
|
224
|
+
src: t.src,
|
|
225
|
+
type: t.type,
|
|
226
|
+
isMain: t.isMain === !0
|
|
227
|
+
}] : []) : [], U = (t, n) => {
|
|
228
|
+
let r = `${p}/${n}`, i = `${r}/${c}`, a = `npx plitzi space pull brings it again — or delete ${r}/, and the space renders no ${n}.`;
|
|
229
|
+
if (!C(t, i, "file")) return { problem: y("vendor-manifest-missing", `${r}/`, `${r}/ has no ${c}: the server runs a built plugin by what its manifest names, so ${n} does not run.`, a) };
|
|
230
|
+
let o;
|
|
231
|
+
try {
|
|
232
|
+
o = JSON.parse(h(m.join(t, i), "utf-8"));
|
|
233
|
+
} catch (e) {
|
|
234
|
+
return { problem: y("vendor-manifest-invalid", i, `${i} is not JSON (${e instanceof Error ? e.message : String(e)}), so ${n} does not run.`, a) };
|
|
235
|
+
}
|
|
236
|
+
if (!e(o)) return { problem: y("vendor-manifest-invalid", i, `${i} is not a manifest, so ${n} does not run.`, a) };
|
|
237
|
+
let s = H(o), l = s.find((e) => e.type === "script" && e.isMain) ?? s.find((e) => e.type === "script");
|
|
238
|
+
if (!l) return { problem: y("vendor-script-missing", i, `${i} names no script to run, so ${n} does not run.`, a) };
|
|
239
|
+
if (!C(t, m.posix.join(r, l.src), "file")) return { problem: y("vendor-script-missing", i, `${i} names ${l.src} as the script to run, and ${r}/${l.src} is not there, so ${n} does not run.`, a) };
|
|
240
|
+
let u = s.find((e) => e.type === "style");
|
|
241
|
+
return {
|
|
242
|
+
script: m.join(t, r, l.src),
|
|
243
|
+
...u ? { style: m.join(t, r, u.src) } : {},
|
|
244
|
+
version: typeof o.version == "string" ? o.version : "1.0.0",
|
|
245
|
+
...typeof o.functions == "string" ? { functions: m.join(t, r, o.functions) } : {}
|
|
246
|
+
};
|
|
247
|
+
}, W = (e) => {
|
|
248
|
+
let { files: t, folders: n } = S(m.join(e, i)), r = t.filter((e) => !b.has(e) && e !== "declarations.ts").map((e) => {
|
|
249
|
+
let { name: t } = m.parse(e), n = t !== "index" && N(t) || "<Name>";
|
|
250
|
+
return y("plugin-file-loose", `${i}/${e}`, `${i}/${e} is a file, and every plugin is a folder of ${i}/: the server reads nothing of it.`, `Give it a folder with an index.ts that exports it by default — ${i}/${n}/${e} and ${i}/${n}/index.ts, as npx plitzi plugin add writes them — or move it out of ${i}/.`);
|
|
251
|
+
}), a = S(m.join(e, p)).folders, o = new Set(n.filter((e) => x.test(e)).map(M)), s = a.filter((e) => o.has(e)).map((e) => y("plugin-shadowed", `${p}/${e}/`, `${e} is both ${p}/${e}/, as it was built, and a folder of ${i}/: the server runs the built one, and a change to the source shows nowhere.`, `Delete ${p}/${e}/: the source is the plugin now.`)), c = a.flatMap((t) => {
|
|
252
|
+
let n = U(e, t);
|
|
253
|
+
return "problem" in n ? [n.problem] : [];
|
|
254
|
+
});
|
|
255
|
+
return [
|
|
256
|
+
...n.flatMap((t) => B(e, t)),
|
|
257
|
+
...V(n),
|
|
258
|
+
...r,
|
|
259
|
+
...s,
|
|
260
|
+
...c
|
|
261
|
+
];
|
|
262
|
+
}, G = (e, t) => t.map((t) => e.find((e) => E(e, t))).find((e) => e !== void 0), K = (e) => (t) => {
|
|
263
|
+
for (let n of S(m.join(e, t)).folders) {
|
|
264
|
+
let r = G(S(m.join(e, t, n)).files, [...o, a]);
|
|
265
|
+
if (r) return `${t}/${n}/${r}`;
|
|
266
|
+
}
|
|
267
|
+
}, q = (e) => (t) => {
|
|
268
|
+
let n = G(S(m.join(e, t)).files, ["index.ts"]);
|
|
269
|
+
return n ? `${t}/${n}` : void 0;
|
|
270
|
+
}, J = (e, { mode: a, space: o }) => [
|
|
271
|
+
{
|
|
272
|
+
at: i,
|
|
273
|
+
reads: `the server builds plugins from ${i}/ only`,
|
|
274
|
+
holds: K(e)
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
at: r,
|
|
278
|
+
reads: `the project's functions are built from ${r}/ only`,
|
|
279
|
+
holds: q(e)
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
at: u,
|
|
283
|
+
reads: `the space's runtime is run from ${u}/ only`,
|
|
284
|
+
holds: q(e)
|
|
285
|
+
},
|
|
286
|
+
...o === "local" ? [{
|
|
287
|
+
at: d,
|
|
288
|
+
reads: `the server's entry point and ${t} import the space from ${f}`,
|
|
289
|
+
holds: q(e)
|
|
290
|
+
}] : [],
|
|
291
|
+
...a === "server" ? [{
|
|
292
|
+
at: n,
|
|
293
|
+
reads: `the server reads the project's data from ${n}/ only (/data/<file>, ctx.data)`
|
|
294
|
+
}] : [],
|
|
295
|
+
{
|
|
296
|
+
at: l,
|
|
297
|
+
reads: `the server serves ${l}/ only, at the site's root`
|
|
298
|
+
}
|
|
299
|
+
], Y = (e, t) => {
|
|
300
|
+
let n = m.posix.dirname(t), r = m.posix.basename(t), i = n === "." ? "src" : ".", a = S(m.join(e, n)).folders.filter((e) => k(e, r)).map((e) => m.posix.join(n, e)), o = S(m.join(e, i)).folders.filter((e) => e === r || k(e, r)).map((e) => m.posix.join(i, e));
|
|
301
|
+
return [...a, ...o];
|
|
302
|
+
}, X = (e, t) => J(e, t).flatMap(({ at: t, reads: n, holds: r }) => Y(e, t).map((i) => {
|
|
303
|
+
let a = r?.(i), o = E(i, t), s = `did you mean ${t}/? ${D(n)}.${o ? ` ${A}` : ""}`, c = `Move it: ${j(i, t)}`;
|
|
304
|
+
o ? c = `Rename it: ${j(i, t)}` : C(e, t, "folder") && (c = `Move what it holds into ${t}/, and delete it.`);
|
|
305
|
+
let l = {
|
|
306
|
+
action: "move",
|
|
307
|
+
from: `${i}/`,
|
|
308
|
+
to: `${t}/`
|
|
309
|
+
};
|
|
310
|
+
return a ? y("folder-misplaced", `${i}/`, `${i}/ holds ${a}, and nothing reads it there — ${s}`, c, l) : y("folder-near-miss", `${i}/`, `${i}/ is read by nothing — ${s}`, c, l);
|
|
311
|
+
})), re = (e, n) => {
|
|
312
|
+
if (!C(e, f, "file")) return n.some((e) => e.code === "folder-misplaced" && e.autofix?.action === "move" && e.autofix.to === "src/space/") ? [] : L(e, {
|
|
313
|
+
folder: d,
|
|
314
|
+
accepted: ["index.ts"],
|
|
315
|
+
code: "space-entry-missing",
|
|
316
|
+
lost: `the server's entry point and ${t}, which import the space from ${f}, do not start`,
|
|
317
|
+
write: `Write ${f} exporting the space — export const space = { name, permanentUrl, pages } — or bring back the one git has: git checkout -- ${f}`
|
|
318
|
+
});
|
|
319
|
+
let r = h(m.join(e, f), "utf-8"), i = /^\s*export\s+default\b/m.test(r), a = /\bexport\s+(?:const|let|var|function)\s+space\b/.test(r) || /\bexport\s*\{[^}]*\bspace\b[^}]*\}/.test(r);
|
|
320
|
+
return i && !a ? [y("space-default-export", f, `${f} exports the space by default, and it is imported by name — import { space } from './space/index.ts' — so the server's entry point and ${t} find no space.`, "Export it as `export const space = …` instead of `export default …`.")] : [];
|
|
321
|
+
}, ie = (e) => e.split("\n").map((e) => e.replace(/^(\s*(?:export\s+)?[A-Za-z_][A-Za-z0-9_]*\s*=).*$/, "$1")).join("\n"), ae = (e) => {
|
|
322
|
+
let t = S(e).files, n = t.includes(".env"), r = t.includes(".env.example"), i = w(e, "src", /* @__PURE__ */ new Set(["node_modules"])).filter((e) => m.posix.basename(e) === ".env"), a = !n && i.length === 1, o = i.map((e) => y("env-in-src", e, `${e} is never read: Node reads the project's settings from the .env at its root, as its scripts start it (--env-file-if-exists=.env).`, a ? `Move it to the root: mv ${e} .env` : `Copy what it sets into the root's .env, then delete ${e}.`, a ? {
|
|
323
|
+
action: "move",
|
|
324
|
+
from: e,
|
|
325
|
+
to: ".env"
|
|
326
|
+
} : void 0)), s = n || o.length > 0 ? [] : [y("env-missing", ".env", ".env is missing at the project’s root: none of its settings is set — the keys and secrets its code reads from process.env.", r ? "Copy .env.example and fill it in: cp .env.example .env" : "Write .env with the settings the project reads (process.env.*), and .env.example naming them.", r ? {
|
|
327
|
+
action: "copy",
|
|
328
|
+
from: ".env.example",
|
|
329
|
+
to: ".env"
|
|
330
|
+
} : void 0)], c = r ? [] : [y("env-example-missing", ".env.example", ".env.example is missing: committed where .env never is, it names the settings .env holds, with no secret in them — so a clone knows what to fill in.", n ? "Write it from .env with every value left empty, and commit it." : "Write it — each setting the project reads, as KEY= with no value — and commit it.", n ? {
|
|
331
|
+
action: "write",
|
|
332
|
+
file: ".env.example",
|
|
333
|
+
contents: ie(h(m.join(e, ".env"), "utf-8"))
|
|
334
|
+
} : void 0)];
|
|
335
|
+
return [
|
|
336
|
+
...o,
|
|
337
|
+
...s,
|
|
338
|
+
...c
|
|
339
|
+
];
|
|
340
|
+
}, oe = (e) => w(e, n).filter((e) => !b.has(m.posix.basename(e)) && !e.endsWith(".json")).map((e) => y("data-not-json", e, `${e} is not JSON: a provider's /data/<file> and ctx.data read JSON files only, and plitzi space push leaves it behind.`, `Keep it as JSON (${e.replace(/\.[^./]*$/, "")}.json), or move it out of ${n}/.`)), se = /^\.env(?:\..*)?$|\.(?:pem|key|p12|pfx|jks|keystore|sqlite3?|db|sql|dump)$|secret|credential|password|passwd|private[-_.]?key|id_rsa|id_ed25519|service[-_]?account/i, ce = (e, t) => {
|
|
341
|
+
let r = w(e, l, /* @__PURE__ */ new Set(["node_modules"])), i = r.filter((e) => se.test(m.posix.basename(e))).map((e) => y("public-secret-file", e, `${e} is served to anyone who asks, as it is — everything in ${l}/ is on the internet once the project is deployed — and its name says it holds a secret, a key or a database.`, `Take it out of ${l}/: settings go in the root's .env${t === "server" ? `, data only the server reads in ${n}/` : ""}.`)), a = `${l}/data`, o = t === "server" ? r.filter((e) => e.startsWith(`${a}/`) && e.endsWith(".json")) : [], s = o.slice(0, 3).map((e) => m.posix.basename(e)), c = o.length > 0 ? [y("public-data", `${a}/`, `${a}/ holds ${String(o.length)} JSON file${o.length === 1 ? "" : "s"} (${s.join(", ")}${o.length > s.length ? ", …" : ""}), served to anyone who asks: every visitor can read all of ${o.length === 1 ? "it" : "them"}, not only what a page shows.`, `Data only the server should read goes in ${n}/ — a provider reads it on the server (runtime: 'server', query: '/data/<file>'), a function with ctx.data('<file>'), and neither serves the file. What every visitor may read can stay.`)] : [];
|
|
342
|
+
return [...i, ...c];
|
|
343
|
+
}, Z = (t) => {
|
|
344
|
+
try {
|
|
345
|
+
let n = JSON.parse(h(m.join(t, "package.json"), "utf-8"));
|
|
346
|
+
return e(n) && [n.dependencies, n.devDependencies].some((t) => e(t) && "@plitzi/sdk-server" in t);
|
|
347
|
+
} catch {
|
|
348
|
+
return !1;
|
|
349
|
+
}
|
|
350
|
+
}, le = (e, n) => ({
|
|
351
|
+
mode: n.mode ?? (Z(e) ? "server" : "client"),
|
|
352
|
+
space: n.space ?? (C(e, "src/space", "folder") || C(e, t, "file") ? "local" : "cloud")
|
|
353
|
+
}), Q = (e, t = {}) => {
|
|
354
|
+
let n = le(e, t), i = X(e, n), a = [
|
|
355
|
+
...W(e),
|
|
356
|
+
...R(e, {
|
|
357
|
+
folder: r,
|
|
358
|
+
accepted: ["index.ts"],
|
|
359
|
+
code: "functions-entry-missing",
|
|
360
|
+
lost: "none of the project’s functions runs",
|
|
361
|
+
write: `Write ${r}/index.ts exporting defineFunctions({ … }) by default.`
|
|
362
|
+
}),
|
|
363
|
+
...R(e, {
|
|
364
|
+
folder: u,
|
|
365
|
+
accepted: ["index.ts"],
|
|
366
|
+
code: "runtime-entry-missing",
|
|
367
|
+
lost: "the space’s runtime does not run",
|
|
368
|
+
write: `Write ${u}/index.ts exporting defineRuntime(…) by default — npx plitzi runtime add writes one.`
|
|
369
|
+
}),
|
|
370
|
+
...n.space === "local" ? re(e, i) : [],
|
|
371
|
+
...i,
|
|
372
|
+
...ae(e),
|
|
373
|
+
...n.mode === "server" ? oe(e) : [],
|
|
374
|
+
...ce(e, n.mode)
|
|
375
|
+
];
|
|
376
|
+
return [...a.filter((e) => e.level === "error"), ...a.filter((e) => e.level === "warning")];
|
|
377
|
+
}, ue = (e) => `${e.message}\n → ${e.fix}`, $ = class extends Error {
|
|
378
|
+
#e;
|
|
379
|
+
get findings() {
|
|
380
|
+
return this.#e;
|
|
381
|
+
}
|
|
382
|
+
constructor(e) {
|
|
383
|
+
let t = e.length === 1 ? "one error" : `${String(e.length)} errors`, n = e.map((e, t) => `${String(t + 1)}. ${e.message}\n → ${e.fix}`).join("\n\n"), r = e.filter((e) => e.autofix).length, i = r === e.length ? "these fixes" : `${String(r)} of these fixes`, a = r > 0 ? `npx plitzi doctor --fix makes ${i} itself.` : "npx plitzi doctor says these with the rest of the project.";
|
|
384
|
+
super(`The project is not laid out as Plitzi reads it — ${t}:\n\n${n}\n\n${a}`), this.name = "ProjectLayoutError", this.#e = e;
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
Object.defineProperty($, "name", { value: "ProjectLayoutError" });
|
|
388
|
+
var de = (e, t = {}) => {
|
|
389
|
+
let n = Q(e, t), r = n.filter((e) => e.level === "error");
|
|
390
|
+
if (r.length > 0) throw new $(r);
|
|
391
|
+
return n;
|
|
392
|
+
};
|
|
393
|
+
//#endregion
|
|
394
|
+
export { v as PROJECT_LAYOUT_CODES, $ as ProjectLayoutError, de as assertProjectLayout, B as checkPluginFolder, Q as checkProjectLayout, P as elementEntry, ue as layoutFindingText, F as pluginEntry, M as pluginTypeOf, U as readVendorPlugin };
|