@gallop.software/canon 2.5.0 → 2.7.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.
- package/dist/cli/commands/generate.js +78 -2
- package/dist/cli/commands/validate.d.ts +9 -0
- package/dist/cli/commands/validate.js +167 -0
- package/dist/cli/index.js +17 -1
- package/dist/eslint/configs/recommended.d.ts +3 -0
- package/dist/eslint/configs/recommended.js +7 -1
- package/dist/eslint/index.d.ts +12 -0
- package/dist/eslint/index.js +11 -2
- package/dist/eslint/rules/no-arbitrary-colors.d.ts +5 -0
- package/dist/eslint/rules/no-arbitrary-colors.js +80 -0
- package/dist/eslint/rules/no-cross-zone-imports.d.ts +6 -0
- package/dist/eslint/rules/no-cross-zone-imports.js +99 -0
- package/dist/eslint/rules/no-data-imports.d.ts +5 -0
- package/dist/eslint/rules/no-data-imports.js +49 -0
- package/package.json +1 -1
- package/schema.json +40 -0
- package/dist/eslint/configs/speedwell.d.ts +0 -13
- package/dist/eslint/configs/speedwell.js +0 -20
|
@@ -52,7 +52,7 @@ function generateCursorrules() {
|
|
|
52
52
|
lines.push('This file is auto-generated from @gallop.software/canon. Do not edit manually.');
|
|
53
53
|
lines.push('Regenerate with: npm run generate:ai-rules');
|
|
54
54
|
lines.push('');
|
|
55
|
-
// Tech stack (
|
|
55
|
+
// Tech stack (Canon-compatible templates)
|
|
56
56
|
lines.push('## Tech Stack');
|
|
57
57
|
lines.push('');
|
|
58
58
|
lines.push('- Next.js 16 with App Router');
|
|
@@ -142,6 +142,82 @@ function generateCursorrules() {
|
|
|
142
142
|
lines.push('- Use `classnames` package - use `clsx` instead');
|
|
143
143
|
lines.push('- Use inline styles for hover states - use Tailwind classes');
|
|
144
144
|
lines.push('');
|
|
145
|
+
// File & Folder Authority section
|
|
146
|
+
lines.push('## File & Folder Authority');
|
|
147
|
+
lines.push('');
|
|
148
|
+
lines.push('These rules govern what AI is allowed and forbidden to do when creating, moving, or modifying files and folders.');
|
|
149
|
+
lines.push('');
|
|
150
|
+
lines.push('### Defined `/src` Structure');
|
|
151
|
+
lines.push('');
|
|
152
|
+
lines.push('```');
|
|
153
|
+
lines.push('src/');
|
|
154
|
+
lines.push('├── app/ # Routes, layouts, metadata (Next.js App Router)');
|
|
155
|
+
lines.push('├── blocks/ # Page-level content sections');
|
|
156
|
+
lines.push('├── blog/ # Blog content (archive content type)');
|
|
157
|
+
lines.push('├── components/ # Reusable UI primitives');
|
|
158
|
+
lines.push('├── hooks/ # Custom React hooks');
|
|
159
|
+
lines.push('├── styles/ # CSS, Tailwind, fonts');
|
|
160
|
+
lines.push('├── template/ # Template-level components');
|
|
161
|
+
lines.push('├── tools/ # Utility tools');
|
|
162
|
+
lines.push('├── types/ # TypeScript types');
|
|
163
|
+
lines.push('├── utils/ # Utility functions');
|
|
164
|
+
lines.push('└── state.ts # Global state');
|
|
165
|
+
lines.push('```');
|
|
166
|
+
lines.push('');
|
|
167
|
+
lines.push('### App Router Structure');
|
|
168
|
+
lines.push('');
|
|
169
|
+
lines.push('Routes must use Next.js route groups. At minimum, `(default)` must exist:');
|
|
170
|
+
lines.push('');
|
|
171
|
+
lines.push('```');
|
|
172
|
+
lines.push('src/app/');
|
|
173
|
+
lines.push('├── (default)/ # Required - default layout group');
|
|
174
|
+
lines.push('│ ├── layout.tsx');
|
|
175
|
+
lines.push('│ └── {routes}/');
|
|
176
|
+
lines.push('├── (hero)/ # Optional - hero layout variant');
|
|
177
|
+
lines.push('├── api/ # API routes (exception - no grouping)');
|
|
178
|
+
lines.push('├── layout.tsx # Root layout');
|
|
179
|
+
lines.push('└── metadata.tsx # Shared metadata');
|
|
180
|
+
lines.push('```');
|
|
181
|
+
lines.push('');
|
|
182
|
+
lines.push('- All page routes must be inside a route group (parentheses folder)');
|
|
183
|
+
lines.push('- Never create routes directly under `src/app/` (except `api/`, root files)');
|
|
184
|
+
lines.push('- New route groups are allowed freely when a new layout variant is needed');
|
|
185
|
+
lines.push('');
|
|
186
|
+
lines.push('### File Structure Rules');
|
|
187
|
+
lines.push('');
|
|
188
|
+
lines.push('**Blocks:**');
|
|
189
|
+
lines.push('- Always single files directly in `src/blocks/`');
|
|
190
|
+
lines.push('- Never create folders inside `src/blocks/`');
|
|
191
|
+
lines.push('- Example: `src/blocks/hero-1.tsx`, `src/blocks/testimonial-3.tsx`');
|
|
192
|
+
lines.push('');
|
|
193
|
+
lines.push('**Components:**');
|
|
194
|
+
lines.push('- Simple components: Single file in `src/components/`');
|
|
195
|
+
lines.push('- Complex components: Folder with `index.tsx`');
|
|
196
|
+
lines.push('- Use folders when component has multiple sub-files');
|
|
197
|
+
lines.push('');
|
|
198
|
+
lines.push('### DO - What AI IS Allowed To Do');
|
|
199
|
+
lines.push('');
|
|
200
|
+
lines.push('- Create files only inside existing Canon-defined zones');
|
|
201
|
+
lines.push('- Place new files in the zone that matches their architectural role');
|
|
202
|
+
lines.push('- Follow existing folder conventions within a zone');
|
|
203
|
+
lines.push('- Reuse existing folders when possible');
|
|
204
|
+
lines.push('- Create new route groups in `src/app/` when new layouts are needed');
|
|
205
|
+
lines.push('- Create new archive content folders (like `blog/`, `portfolio/`) in `/src`');
|
|
206
|
+
lines.push('- Create dotfiles/directories at project root (`.github/`, `.cursor/`, etc.)');
|
|
207
|
+
lines.push('- Ask for confirmation if the correct zone is ambiguous');
|
|
208
|
+
lines.push('');
|
|
209
|
+
lines.push('### DO NOT - What AI Is Forbidden To Do');
|
|
210
|
+
lines.push('');
|
|
211
|
+
lines.push('- Create new top-level directories (except dotfiles)');
|
|
212
|
+
lines.push('- Create new folders in `/src` (except archive content or route groups)');
|
|
213
|
+
lines.push('- Place files outside Canon-defined zones');
|
|
214
|
+
lines.push('- Mix responsibilities across zones (components importing blocks, etc.)');
|
|
215
|
+
lines.push('- Reorganize or move folders without explicit instruction');
|
|
216
|
+
lines.push('- Invent new organizational conventions');
|
|
217
|
+
lines.push('- Create placeholder or speculative files');
|
|
218
|
+
lines.push('- Import from `_scripts/` or `_data/` in runtime code');
|
|
219
|
+
lines.push('- Manually edit files in `_data/` (generated only)');
|
|
220
|
+
lines.push('');
|
|
145
221
|
// Post-edit verification
|
|
146
222
|
lines.push('## Post-Edit Verification');
|
|
147
223
|
lines.push('');
|
|
@@ -167,4 +243,4 @@ export async function generate(options) {
|
|
|
167
243
|
console.log(` ${patterns.length} patterns, ${guarantees.length} guarantees`);
|
|
168
244
|
}
|
|
169
245
|
}
|
|
170
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2NvbW1hbmRzL2dlbmVyYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFBO0FBQ3hCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQzVCLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFjLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBTzFFOztHQUVHO0FBQ0gsU0FBUyxlQUFlLENBQUMsV0FBbUI7SUFDMUMsbURBQW1EO0lBQ25ELE1BQU0sYUFBYSxHQUFHO1FBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLHFDQUFxQyxFQUFFLFdBQVcsQ0FBQztRQUM1RSwyQkFBMkI7UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsV0FBVyxDQUFDO0tBQ3pELENBQUE7SUFFRCxLQUFLLE1BQU0sUUFBUSxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ3JDLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzVCLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDM0MsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsZUFBZSxDQUFDLE9BQWU7SUFDdEMsTUFBTSxJQUFJLEdBQWEsRUFBRSxDQUFBO0lBQ3pCLE1BQU0sR0FBRyxHQUFhLEVBQUUsQ0FBQTtJQUV4Qix5REFBeUQ7SUFDekQsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO0lBQy9ELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FB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UUFDbkUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxNQUFNLGNBQWMsVUFBVSxDQUFDLE1BQU0sYUFBYSxDQUFDLENBQUE7SUFDL0UsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcydcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCdcbmltcG9ydCB7IHZlcnNpb24sIHBhdHRlcm5zLCBjYXRlZ29yaWVzLCBndWFyYW50ZWVzIH0gZnJvbSAnLi4vLi4vaW5kZXguanMnXG5cbmludGVyZmFjZSBHZW5lcmF0ZU9wdGlvbnMge1xuICBvdXRwdXQ6IHN0cmluZ1xuICBmb3JtYXQ6ICdjdXJzb3JydWxlcycgfCAnbWFya2Rvd24nXG59XG5cbi8qKlxuICogUmVhZCBhIHBhdHRlcm4gbWFya2Rvd24gZmlsZSBhbmQgZXh0cmFjdCBzZWN0aW9uc1xuICovXG5mdW5jdGlvbiByZWFkUGF0dGVybkZpbGUocGF0dGVybkZpbGU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAvLyBUcnkgdG8gZmluZCB0aGUgY2Fub24gcGFja2FnZSBwYXR0ZXJucyBkaXJlY3RvcnlcbiAgY29uc3QgcG9zc2libGVQYXRocyA9IFtcbiAgICBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgJ25vZGVfbW9kdWxlcy9AZ2FsbG9wLnNvZnR3YXJlL2Nhbm9uJywgcGF0dGVybkZpbGUpLFxuICAgIC8vIEZhbGxiYWNrIGZvciBkZXZlbG9wbWVudFxuICAgIHBhdGguam9pbihpbXBvcnQubWV0YS5kaXJuYW1lLCAnLi4vLi4vLi4vJywgcGF0dGVybkZpbGUpLFxuICBdXG5cbiAgZm9yIChjb25zdCBmaWxlUGF0aCBvZiBwb3NzaWJsZVBhdGhzKSB7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG4gICAgICByZXR1cm4gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCAndXRmLTgnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsXG59XG5cbi8qKlxuICogRXh0cmFjdCBleGFtcGxlcyBmcm9tIHBhdHRlcm4gbWFya2Rvd25cbiAqL1xuZnVuY3Rpb24gZXh0cmFjdEV4YW1wbGVzKGNvbnRlbnQ6IHN0cmluZyk6IHsgZ29vZDogc3RyaW5nW107IGJhZDogc3RyaW5nW10gfSB7XG4gIGNvbnN0IGdvb2Q6IHN0cmluZ1tdID0gW11cbiAgY29uc3QgYmFkOiBzdHJpbmdbXSA9IFtdXG5cbiAgLy8gRmluZCBjb2RlIGJsb2NrcyBhZnRlciBcIiMjIyBHb29kXCIgb3IgXCIjIyMgQmFkXCIgaGVhZGVyc1xuICBjb25zdCBnb29kTWF0Y2ggPSBjb250ZW50Lm1hdGNoKC8jIyMgR29vZFxccypcXG5gYGBbXFxzXFxTXSo/YGBgL2cpXG4gIGNvbnN0IGJhZE1hdGNoID0gY29udGVudC5tYXRjaCgvIyMjIEJhZFxccypcXG5gYGBbXFxzXFxTXSo/YGBgL2cpXG5cbiAgaWYgKGdvb2RNYXRjaCkge1xuICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgZ29vZE1hdGNoKSB7XG4gICAgICBjb25zdCBjb2RlID0gbWF0Y2gucmVwbGFjZSgvIyMjIEdvb2RcXHMqXFxuLywgJycpLnRyaW0oKVxuICAgICAgZ29vZC5wdXNoKGNvZGUpXG4gICAgfVxuICB9XG5cbiAgaWYgKGJhZE1hdGNoKSB7XG4gICAgZm9yIChjb25zdCBtYXRjaCBvZiBiYWRNYXRjaCkge1xuICAgICAgY29uc3QgY29kZSA9IG1hdGNoLnJlcGxhY2UoLyMjIyBCYWRcXHMqXFxuLywgJycpLnRyaW0oKVxuICAgICAgYmFkLnB1c2goY29kZSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBnb29kLCBiYWQgfVxufVxuXG4vKipcbiAqIEdlbmVyYXRlIC5jdXJzb3JydWxlcyBjb250ZW50IGZyb20gQ2Fub25cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVDdXJzb3JydWxlcygpOiBzdHJpbmcge1xuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXVxuXG4gIC8vIEhlYWRlclxuICBsaW5lcy5wdXNoKGAjIEdhbGxvcCBDYW5vbiB2JHt2ZXJzaW9ufSAtIEFJIFJ1bGVzYClcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnVGhpcyBmaWxlIGlzIGF1dG8tZ2VuZXJhdGVkIGZyb20gQGdhbGxvcC5zb2Z0d2FyZS9jYW5vbi4gRG8gbm90IGVkaXQgbWFudWFsbHkuJylcbiAgbGluZXMucHVzaCgnUmVnZW5lcmF0ZSB3aXRoOiBucG0gcnVuIGdlbmVyYXRlOmFpLXJ1bGVzJylcbiAgbGluZXMucHVzaCgnJylcblxuICAvLyBUZWNoIHN0YWNrIChmcm9tIHNwZWVkd2VsbCBjb250ZXh0KVxuICBsaW5lcy5wdXNoKCcjIyBUZWNoIFN0YWNrJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnLSBOZXh0LmpzIDE2IHdpdGggQXBwIFJvdXRlcicpXG4gIGxpbmVzLnB1c2goJy0gUmVhY3QgMTknKVxuICBsaW5lcy5wdXNoKCctIFR5cGVTY3JpcHQnKVxuICBsaW5lcy5wdXNoKCctIFRhaWx3aW5kIENTUyB2NCcpXG4gIGxpbmVzLnB1c2goJy0gY2xzeCBmb3IgY29uZGl0aW9uYWwgY2xhc3MgbmFtZXMnKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIC8vIEVuZm9yY2VkIHBhdHRlcm5zIChFU0xpbnQgcnVsZXMpXG4gIGxpbmVzLnB1c2goJyMjIEVuZm9yY2VkIFBhdHRlcm5zIChFU0xpbnQpJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnVGhlc2UgcGF0dGVybnMgYXJlIGVuZm9yY2VkIGJ5IGBAZ2FsbG9wLnNvZnR3YXJlL2Nhbm9uL2VzbGludGAuIFZpb2xhdGlvbnMgd2lsbCBiZSBmbGFnZ2VkLicpXG4gIGxpbmVzLnB1c2goJycpXG5cbiAgY29uc3QgZW5mb3JjZWRQYXR0ZXJucyA9IHBhdHRlcm5zLmZpbHRlcihwID0+IHAuZW5mb3JjZW1lbnQgPT09ICdlc2xpbnQnICYmIHAucnVsZSlcbiAgZm9yIChjb25zdCBwYXR0ZXJuIG9mIGVuZm9yY2VkUGF0dGVybnMpIHtcbiAgICBsaW5lcy5wdXNoKGAjIyMgJHtwYXR0ZXJuLmlkfTogJHtwYXR0ZXJuLnRpdGxlfWApXG4gICAgbGluZXMucHVzaCgnJylcbiAgICBsaW5lcy5wdXNoKHBhdHRlcm4uc3VtbWFyeSlcbiAgICBsaW5lcy5wdXNoKCcnKVxuICAgIGxpbmVzLnB1c2goYC0gKipFU0xpbnQgUnVsZToqKiBcXGAke3BhdHRlcm4ucnVsZX1cXGBgKVxuICAgIGxpbmVzLnB1c2goYC0gKipDYXRlZ29yeToqKiAke3BhdHRlcm4uY2F0ZWdvcnl9YClcbiAgICBsaW5lcy5wdXNoKCcnKVxuXG4gICAgLy8gVHJ5IHRvIHJlYWQgYW5kIGluY2x1ZGUgZXhhbXBsZXNcbiAgICBjb25zdCBjb250ZW50ID0gcmVhZFBhdHRlcm5GaWxlKHBhdHRlcm4uZmlsZSlcbiAgICBpZiAoY29udGVudCkge1xuICAgICAgY29uc3QgeyBnb29kLCBiYWQgfSA9IGV4dHJhY3RFeGFtcGxlcyhjb250ZW50KVxuICAgICAgaWYgKGJhZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxpbmVzLnB1c2goJyoqQmFkOioqJylcbiAgICAgICAgbGluZXMucHVzaCgnJylcbiAgICAgICAgbGluZXMucHVzaChiYWRbMF0pXG4gICAgICAgIGxpbmVzLnB1c2goJycpXG4gICAgICB9XG4gICAgICBpZiAoZ29vZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxpbmVzLnB1c2goJyoqR29vZDoqKicpXG4gICAgICAgIGxpbmVzLnB1c2goJycpXG4gICAgICAgIGxpbmVzLnB1c2goZ29vZFswXSlcbiAgICAgICAgbGluZXMucHVzaCgnJylcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBEb2N1bWVudGF0aW9uIHBhdHRlcm5zXG4gIGxpbmVzLnB1c2goJyMjIERvY3VtZW50YXRpb24gUGF0dGVybnMnKVxuICBsaW5lcy5wdXNoKCcnKVxuICBsaW5lcy5wdXNoKCdUaGVzZSBwYXR0ZXJucyBhcmUgbm90IGVuZm9yY2VkIGJ5IEVTTGludCBidXQgc2hvdWxkIGJlIGZvbGxvd2VkLicpXG4gIGxpbmVzLnB1c2goJycpXG5cbiAgY29uc3QgZG9jUGF0dGVybnMgPSBwYXR0ZXJucy5maWx0ZXIocCA9PiBwLmVuZm9yY2VtZW50ID09PSAnZG9jdW1lbnRhdGlvbicpXG4gIGZvciAoY29uc3QgcGF0dGVybiBvZiBkb2NQYXR0ZXJucykge1xuICAgIGxpbmVzLnB1c2goYCMjIyAke3BhdHRlcm4uaWR9OiAke3BhdHRlcm4udGl0bGV9YClcbiAgICBsaW5lcy5wdXNoKCcnKVxuICAgIGxpbmVzLnB1c2gocGF0dGVybi5zdW1tYXJ5KVxuICAgIGxpbmVzLnB1c2goJycpXG4gIH1cblxuICAvLyBHdWFyYW50ZWVzXG4gIGxpbmVzLnB1c2goJyMjIENhbm9uIEd1YXJhbnRlZXMnKVxuICBsaW5lcy5wdXNoKCcnKVxuICBsaW5lcy5wdXNoKCdGb2xsb3dpbmcgdGhlc2UgcGF0dGVybnMgcHJvdmlkZXMgdGhlc2UgZ3VhcmFudGVlczonKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIGZvciAoY29uc3QgZ3VhcmFudGVlIG9mIGd1YXJhbnRlZXMpIHtcbiAgICBsaW5lcy5wdXNoKGAtICoqJHtndWFyYW50ZWUubmFtZX0qKiAoJHtndWFyYW50ZWUuaWR9KTogUGF0dGVybnMgJHtndWFyYW50ZWUucGF0dGVybnMuam9pbignLCAnKX1gKVxuICB9XG4gIGxpbmVzLnB1c2goJycpXG5cbiAgLy8gUXVpY2sgcmVmZXJlbmNlIGZvciBjb21wb25lbnRzXG4gIGxpbmVzLnB1c2goJyMjIENvbXBvbmVudCBRdWljayBSZWZlcmVuY2UnKVxuICBsaW5lcy5wdXNoKCcnKVxuICBsaW5lcy5wdXNoKCcjIyMgVHlwb2dyYXBoeScpXG4gIGxpbmVzLnB1c2goJy0gYEhlYWRpbmdgIC0gcHJvcHM6IGBhc2AsIGBjb2xvcmAsIGBtYXJnaW5gLCBgZm9udFNpemVgLCBgZm9udFdlaWdodGAsIGB0ZXh0QWxpZ25gJylcbiAgbGluZXMucHVzaCgnLSBgUGFyYWdyYXBoYCAtIHByb3BzOiBgY29sb3JgLCBgbWFyZ2luYCwgYGZvbnRTaXplYCwgYGxpbmVIZWlnaHRgLCBgdGV4dEFsaWduYCcpXG4gIGxpbmVzLnB1c2goJy0gYFNwYW5gIC0gcHJvcHM6IGBjb2xvcmAsIGBtYXJnaW5gLCBgZm9udFNpemVgIChpbmxpbmUgdGV4dCwgbWItMCBkZWZhdWx0KScpXG4gIGxpbmVzLnB1c2goJy0gYExhYmVsYCAtIHByb3BzOiBgY29sb3JgLCBgbWFyZ2luYCwgYGZvbnRTaXplYCwgYGZvbnRXZWlnaHRgLCBgdGV4dEFsaWduYCcpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJyMjIyBMYXlvdXQnKVxuICBsaW5lcy5wdXNoKCctIGBTZWN0aW9uYCAtIHNlbWFudGljIHNlY3Rpb24gd3JhcHBlcicpXG4gIGxpbmVzLnB1c2goJy0gYENvbHVtbnNgIC0gZ3JpZCBsYXlvdXQsIHByb3BzOiBgY29sc2AsIGBnYXBgLCBgYWxpZ25gJylcbiAgbGluZXMucHVzaCgnLSBgQ29sdW1uYCAtIGNvbHVtbiBjaGlsZCcpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJyMjIyBJbnRlcmFjdGl2ZScpXG4gIGxpbmVzLnB1c2goJy0gYEJ1dHRvbmAgLSBwcm9wczogYGhyZWZgLCBgdmFyaWFudGAsIGBpY29uYCwgYGljb25QbGFjZW1lbnRgLCBgbWFyZ2luYCcpXG4gIGxpbmVzLnB1c2goJy0gYEljb25gIC0gSWNvbmlmeSBpY29uIHdyYXBwZXInKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIC8vIERvIE5PVCBzZWN0aW9uXG4gIGxpbmVzLnB1c2goJyMjIERvIE5PVCcpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJy0gVXNlIGBcXCd1c2UgY2xpZW50XFwnYCBpbiBibG9ja3MgLSBleHRyYWN0IHRvIGNvbXBvbmVudHMnKVxuICBsaW5lcy5wdXNoKCctIFVzZSByYXcgYDxwPmAgb3IgYDxzcGFuPmAgLSB1c2UgUGFyYWdyYXBoL1NwYW4gY29tcG9uZW50cycpXG4gIGxpbmVzLnB1c2goJy0gVXNlIGNsYXNzTmFtZSBmb3IgbWFyZ2luL2NvbG9yL2ZvbnRTaXplIHdoZW4gY29tcG9uZW50IGhhcyBwcm9wcycpXG4gIGxpbmVzLnB1c2goJy0gVXNlIENvbnRhaW5lciBpbnNpZGUgU2VjdGlvbiAtIFNlY3Rpb24gYWxyZWFkeSBwcm92aWRlcyBjb250YWlubWVudCcpXG4gIGxpbmVzLnB1c2goJy0gVXNlIGBjbGFzc25hbWVzYCBwYWNrYWdlIC0gdXNlIGBjbHN4YCBpbnN0ZWFkJylcbiAgbGluZXMucHVzaCgnLSBVc2UgaW5saW5lIHN0eWxlcyBmb3IgaG92ZXIgc3RhdGVzIC0gdXNlIFRhaWx3aW5kIGNsYXNzZXMnKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIC8vIFBvc3QtZWRpdCB2ZXJpZmljYXRpb25cbiAgbGluZXMucHVzaCgnIyMgUG9zdC1FZGl0IFZlcmlmaWNhdGlvbicpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJ0FmdGVyIGVkaXRpbmcgZmlsZXM6JylcbiAgbGluZXMucHVzaCgnMS4gUnVuIGBucG0gcnVuIGxpbnRgIHRvIGNoZWNrIGZvciBlcnJvcnMnKVxuICBsaW5lcy5wdXNoKCcyLiBGaXggYW55IHZpb2xhdGlvbnMgYmVmb3JlIGNvbW1pdHRpbmcnKVxuICBsaW5lcy5wdXNoKCcnKVxuICBsaW5lcy5wdXNoKCdOb3RlOiBPbmx5IGxpbnQgZmlsZXMgeW91IGVkaXRlZCwgbm90IHRoZSBlbnRpcmUgY29kZWJhc2UuJylcbiAgbGluZXMucHVzaCgnJylcblxuICByZXR1cm4gbGluZXMuam9pbignXFxuJylcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlKG9wdGlvbnM6IEdlbmVyYXRlT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjb250ZW50ID0gZ2VuZXJhdGVDdXJzb3JydWxlcygpXG5cbiAgaWYgKG9wdGlvbnMub3V0cHV0ID09PSAnLScpIHtcbiAgICAvLyBPdXRwdXQgdG8gc3Rkb3V0XG4gICAgY29uc29sZS5sb2coY29udGVudClcbiAgfSBlbHNlIHtcbiAgICAvLyBXcml0ZSB0byBmaWxlXG4gICAgY29uc3Qgb3V0cHV0UGF0aCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBvcHRpb25zLm91dHB1dClcbiAgICBmcy53cml0ZUZpbGVTeW5jKG91dHB1dFBhdGgsIGNvbnRlbnQsICd1dGYtOCcpXG4gICAgY29uc29sZS5sb2coYOKckyBHZW5lcmF0ZWQgJHtvcHRpb25zLm91dHB1dH0gZnJvbSBDYW5vbiB2JHt2ZXJzaW9ufWApXG4gICAgY29uc29sZS5sb2coYCAgJHtwYXR0ZXJucy5sZW5ndGh9IHBhdHRlcm5zLCAke2d1YXJhbnRlZXMubGVuZ3RofSBndWFyYW50ZWVzYClcbiAgfVxufVxuIl19
|
|
246
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2NvbW1hbmRzL2dlbmVyYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFBO0FBQ3hCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQzVCLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFjLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBTzFFOztHQUVHO0FBQ0gsU0FBUyxlQUFlLENBQUMsV0FBbUI7SUFDMUMsbURBQW1EO0lBQ25ELE1BQU0sYUFBYSxHQUFHO1FBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLHFDQUFxQyxFQUFFLFdBQVcsQ0FBQztRQUM1RSwyQkFBMkI7UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsV0FBVyxDQUFDO0tBQ3pELENBQUE7SUFFRCxLQUFLLE1BQU0sUUFBUSxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ3JDLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzVCLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDM0MsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsZUFBZSxDQUFDLE9BQWU7SUFDdEMsTUFBTSxJQUFJLEdBQWEsRUFBRSxDQUFBO0lBQ3pCLE1BQU0sR0FBRyxHQUFhLEVBQUUsQ0FBQTtJQUV4Qix5REFBeUQ7SUFDekQsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO0lBQy9ELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQTtJQUU3RCxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtZQUN0RCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ2pCLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUNiLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxFQUFFLENBQUM7WUFDN0IsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDckQsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNoQixDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUE7QUFDdEIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxtQkFBbUI7SUFDMUIsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFBO0lBRTFCLFNBQVM7SUFDVCxLQUFLLENBQUMsSUFBSSxDQUFDLG1CQUFtQixPQUFPLGFBQWEsQ0FBQyxDQUFBO0lBQ25ELEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLGdGQUFnRixDQUFDLENBQUE7SUFDNUYsS0FBSyxDQUFDLElBQUksQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFBO0lBQ3hELEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFFZCwwQ0FBMEM7SUFDMUMsS0FBSyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQTtJQUMzQixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ2QsS0FBSyxDQUFDLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO0lBQzFDLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDeEIsS0FBSyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUMxQixLQUFLLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUE7SUFDL0IsS0FBSyxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFBO0lBQ2hELEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFFZCxtQ0FBbUM7SUFDbkMsS0FBSyxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFBO0lBQzNDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLDZGQUE2RixDQUFDLENBQUE7SUFDekcsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUVkLE1BQU0sZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLEtBQUssUUFBUSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNuRixLQUFLLE1BQU0sT0FBTyxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFDdkMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLE9BQU8sQ0FBQyxFQUFFLEtBQUssT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7UUFDakQsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUNkLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQzNCLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7UUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLHdCQUF3QixPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQTtRQUNwRCxLQUFLLENBQUMsSUFBSSxDQUFDLG1CQUFtQixPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQTtRQUNqRCxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBRWQsbUNBQW1DO1FBQ25DLE1BQU0sT0FBTyxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDN0MsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQzlDLElBQUksR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDbkIsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtnQkFDdEIsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtnQkFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUNsQixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1lBQ2hCLENBQUM7WUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BCLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7Z0JBQ3ZCLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7Z0JBQ2QsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtnQkFDbkIsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtZQUNoQixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCx5QkFBeUI7SUFDekIsS0FBSyxDQUFDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFBO0lBQ3ZDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLG1FQUFtRSxDQUFDLENBQUE7SUFDL0UsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUVkLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxLQUFLLGVBQWUsQ0FBQyxDQUFBO0lBQzNFLEtBQUssTUFBTSxPQUFPLElBQUksV0FBVyxFQUFFLENBQUM7UUFDbEMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLE9BQU8sQ0FBQyxFQUFFLEtBQUssT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7UUFDakQsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUNkLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQzNCLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDaEIsQ0FBQztJQUVELGFBQWE7SUFDYixLQUFLLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUE7SUFDakMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNkLEtBQUssQ0FBQyxJQUFJLENBQUMscURBQXFELENBQUMsQ0FBQTtJQUNqRSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRWQsS0FBSyxNQUFNLFNBQVMsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUNuQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sU0FBUyxDQUFDLElBQUksT0FBTyxTQUFTLENBQUMsRUFBRSxlQUFlLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNwRyxDQUFDO0lBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUVkLGlDQUFpQztJQUNqQyxLQUFLLENBQUMsSUFBSSxDQUFDLDhCQUE4QixDQUFDLENBQUE7SUFDMUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNkLEtBQUssQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQTtJQUM1QixLQUFLLENBQUMsSUFBSSxDQUFDLHFGQUFxRixDQUFDLENBQUE7SUFDakcsS0FBSyxDQUFDLElBQUksQ0FBQyxpRkFBaUYsQ0FBQyxDQUFBO0lBQzdGLEtBQUssQ0FBQyxJQUFJLENBQUMsNkVBQTZFLENBQUMsQ0FBQTtJQUN6RixLQUFLLENBQUMsSUFBSSxDQUFDLDZFQUE2RSxDQUFDLENBQUE7SUFDekYsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNkLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDeEIsS0FBSyxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFBO0lBQ3BELEtBQUssQ0FBQyxJQUFJLENBQUMsMERBQTBELENBQUMsQ0FBQTtJQUN0RSxLQUFLLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUE7SUFDdkMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNkLEtBQUssQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQTtJQUM3QixLQUFLLENBQUMsSUFBSSxDQUFDLDBFQUEwRSxDQUFDLENBQUE7SUFDdEYsS0FBSyxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFBO0lBQzdDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFFZCxpQkFBaUI7SUFDakIsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQTtJQUN2QixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ2QsS0FBSyxDQUFDLElBQUksQ0FBQywwREFBMEQsQ0FBQyxDQUFBO0lBQ3RFLEtBQUssQ0FBQyxJQUFJLENBQUMsNkRBQTZELENBQUMsQ0FBQTtJQUN6RSxLQUFLLENBQUMsSUFBSSxDQUFDLG9FQUFvRSxDQUFDLENBQUE7SUFDaEYsS0FBSyxDQUFDLElBQUksQ0FBQyx1RUFBdUUsQ0FBQyxDQUFBO0lBQ25GLEtBQUssQ0FBQyxJQUFJLENBQUMsaURBQWlELENBQUMsQ0FBQTtJQUM3RCxLQUFLLENBQUMsSUFBSSxDQUFDLDZEQUE2RCxDQUFDLENBQUE7SUFDekUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUVkLGtDQUFrQztJQUNsQyxLQUFLLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLENBQUE7SUFDeEMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNkLEtBQUssQ0FBQyxJQUFJLENBQUMsa0hBQWtILENBQUMsQ0FBQTtJQUM5SCxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRWQsS0FBSyxDQUFDLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO0lBQzFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2pCLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDbEIsS0FBSyxDQUFDLElBQUksQ0FBQyxvRUFBb0UsQ0FBQyxDQUFBO0lBQ2hGLEtBQUssQ0FBQyxJQUFJLENBQUMsaURBQWlELENBQUMsQ0FBQTtJQUM3RCxLQUFLLENBQUMsSUFBSSxDQUFDLHlEQUF5RCxDQUFDLENBQUE7SUFDckUsS0FBSyxDQUFDLElBQUksQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFBO0lBQ3hELEtBQUssQ0FBQyxJQUFJLENBQUMsd0NBQXdDLENBQUMsQ0FBQTtJQUNwRCxLQUFLLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUE7SUFDdEQsS0FBSyxDQUFDLElBQUksQ0FBQywrQ0FBK0MsQ0FBQyxDQUFBO0lBQzNELEtBQUssQ0FBQyxJQUFJLENBQUMsbUNBQW1DLENBQUMsQ0FBQTtJQUMvQyxLQUFLLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUE7SUFDbEQsS0FBSyxDQUFDLElBQUksQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFBO0lBQ25ELEtBQUssQ0FBQyxJQUFJLENBQUMsa0NBQWtDLENBQUMsQ0FBQTtJQUM5QyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2pCLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFFZCxLQUFLLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLENBQUE7SUFDdEMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNkLEtBQUssQ0FBQyxJQUFJLENBQUMsMkVBQTJFLENBQUMsQ0FBQTtJQUN2RixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ2QsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNqQixLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3RCLEtBQUssQ0FBQyxJQUFJLENBQUMseURBQXlELENBQUMsQ0FBQTtJQUNyRSxLQUFLLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUE7SUFDaEMsS0FBSyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0lBQy9CLEtBQUssQ0FBQyxJQUFJLENBQUMsd0RBQXdELENBQUMsQ0FBQTtJQUNwRSxLQUFLLENBQUMsSUFBSSxDQUFDLDhEQUE4RCxDQUFDLENBQUE7SUFDMUUsS0FBSyxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFBO0lBQ2pELEtBQUssQ0FBQyxJQUFJLENBQUMseUNBQXlDLENBQUMsQ0FBQTtJQUNyRCxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2pCLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLHFFQUFxRSxDQUFDLENBQUE7SUFDakYsS0FBSyxDQUFDLElBQUksQ0FBQyw2RUFBNkUsQ0FBQyxDQUFBO0lBQ3pGLEtBQUssQ0FBQyxJQUFJLENBQUMsMkVBQTJFLENBQUMsQ0FBQTtJQUN2RixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRWQsS0FBSyxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxDQUFBO0lBQ3RDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBQ3pCLEtBQUssQ0FBQyxJQUFJLENBQUMsaURBQWlELENBQUMsQ0FBQTtJQUM3RCxLQUFLLENBQUMsSUFBSSxDQUFDLDZDQUE2QyxDQUFDLENBQUE7SUFDekQsS0FBSyxDQUFDLElBQUksQ0FBQyxvRUFBb0UsQ0FBQyxDQUFBO0lBQ2hGLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUE7SUFDN0IsS0FBSyxDQUFDLElBQUksQ0FBQyx1REFBdUQsQ0FBQyxDQUFBO0lBQ25FLEtBQUssQ0FBQyxJQUFJLENBQUMsK0NBQStDLENBQUMsQ0FBQTtJQUMzRCxLQUFLLENBQUMsSUFBSSxDQUFDLHFEQUFxRCxDQUFDLENBQUE7SUFDakUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUVkLEtBQUssQ0FBQyxJQUFJLENBQUMsbUNBQW1DLENBQUMsQ0FBQTtJQUMvQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ2QsS0FBSyxDQUFDLElBQUksQ0FBQyx5REFBeUQsQ0FBQyxDQUFBO0lBQ3JFLEtBQUssQ0FBQyxJQUFJLENBQUMscUVBQXFFLENBQUMsQ0FBQTtJQUNqRixLQUFLLENBQUMsSUFBSSxDQUFDLG9EQUFvRCxDQUFDLENBQUE7SUFDaEUsS0FBSyxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFBO0lBQ3BELEtBQUssQ0FBQyxJQUFJLENBQUMscUVBQXFFLENBQUMsQ0FBQTtJQUNqRixLQUFLLENBQUMsSUFBSSxDQUFDLDZFQUE2RSxDQUFDLENBQUE7SUFDekYsS0FBSyxDQUFDLElBQUksQ0FBQyw4RUFBOEUsQ0FBQyxDQUFBO0lBQzFGLEtBQUssQ0FBQyxJQUFJLENBQUMseURBQXlELENBQUMsQ0FBQTtJQUNyRSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRWQsS0FBSyxDQUFDLElBQUksQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFBO0lBQ3JELEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDZCxLQUFLLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUE7SUFDbEUsS0FBSyxDQUFDLElBQUksQ0FBQyx5RUFBeUUsQ0FBQyxDQUFBO0lBQ3JGLEtBQUssQ0FBQyxJQUFJLENBQUMsMkNBQTJDLENBQUMsQ0FBQTtJQUN2RCxLQUFLLENBQUMsSUFBSSxDQUFDLHlFQUF5RSxDQUFDLENBQUE7SUFDckYsS0FBSyxDQUFDLElBQUksQ0FBQywyREFBMkQsQ0FBQyxDQUFBO0lBQ3ZFLEtBQUssQ0FBQyxJQUFJLENBQUMseUNBQXlDLENBQUMsQ0FBQTtJQUNyRCxLQUFLLENBQUMsSUFBSSxDQUFDLDJDQUEyQyxDQUFDLENBQUE7SUFDdkQsS0FBSyxDQUFDLElBQUksQ0FBQyx1REFBdUQsQ0FBQyxDQUFBO0lBQ25FLEtBQUssQ0FBQyxJQUFJLENBQUMsb0RBQW9ELENBQUMsQ0FBQTtJQUNoRSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRWQseUJBQXlCO0lBQ3pCLEtBQUssQ0FBQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtJQUN2QyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ2QsS0FBSyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFBO0lBQ2xDLEtBQUssQ0FBQyxJQUFJLENBQUMsMkNBQTJDLENBQUMsQ0FBQTtJQUN2RCxLQUFLLENBQUMsSUFBSSxDQUFDLHlDQUF5QyxDQUFDLENBQUE7SUFDckQsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNkLEtBQUssQ0FBQyxJQUFJLENBQUMsNERBQTRELENBQUMsQ0FBQTtJQUN4RSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRWQsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0FBQ3pCLENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLFFBQVEsQ0FBQyxPQUF3QjtJQUNyRCxNQUFNLE9BQU8sR0FBRyxtQkFBbUIsRUFBRSxDQUFBO0lBRXJDLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUMzQixtQkFBbUI7UUFDbkIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUN0QixDQUFDO1NBQU0sQ0FBQztRQUNOLGdCQUFnQjtRQUNoQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDOUQsRUFBRSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBQzlDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxPQUFPLENBQUMsTUFBTSxnQkFBZ0IsT0FBTyxFQUFFLENBQUMsQ0FBQTtRQUNuRSxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssUUFBUSxDQUFDLE1BQU0sY0FBYyxVQUFVLENBQUMsTUFBTSxhQUFhLENBQUMsQ0FBQTtJQUMvRSxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJ1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJ1xuaW1wb3J0IHsgdmVyc2lvbiwgcGF0dGVybnMsIGNhdGVnb3JpZXMsIGd1YXJhbnRlZXMgfSBmcm9tICcuLi8uLi9pbmRleC5qcydcblxuaW50ZXJmYWNlIEdlbmVyYXRlT3B0aW9ucyB7XG4gIG91dHB1dDogc3RyaW5nXG4gIGZvcm1hdDogJ2N1cnNvcnJ1bGVzJyB8ICdtYXJrZG93bidcbn1cblxuLyoqXG4gKiBSZWFkIGEgcGF0dGVybiBtYXJrZG93biBmaWxlIGFuZCBleHRyYWN0IHNlY3Rpb25zXG4gKi9cbmZ1bmN0aW9uIHJlYWRQYXR0ZXJuRmlsZShwYXR0ZXJuRmlsZTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIC8vIFRyeSB0byBmaW5kIHRoZSBjYW5vbiBwYWNrYWdlIHBhdHRlcm5zIGRpcmVjdG9yeVxuICBjb25zdCBwb3NzaWJsZVBhdGhzID0gW1xuICAgIHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnbm9kZV9tb2R1bGVzL0BnYWxsb3Auc29mdHdhcmUvY2Fub24nLCBwYXR0ZXJuRmlsZSksXG4gICAgLy8gRmFsbGJhY2sgZm9yIGRldmVsb3BtZW50XG4gICAgcGF0aC5qb2luKGltcG9ydC5tZXRhLmRpcm5hbWUsICcuLi8uLi8uLi8nLCBwYXR0ZXJuRmlsZSksXG4gIF1cblxuICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHBvc3NpYmxlUGF0aHMpIHtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhmaWxlUGF0aCkpIHtcbiAgICAgIHJldHVybiBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsICd1dGYtOCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGxcbn1cblxuLyoqXG4gKiBFeHRyYWN0IGV4YW1wbGVzIGZyb20gcGF0dGVybiBtYXJrZG93blxuICovXG5mdW5jdGlvbiBleHRyYWN0RXhhbXBsZXMoY29udGVudDogc3RyaW5nKTogeyBnb29kOiBzdHJpbmdbXTsgYmFkOiBzdHJpbmdbXSB9IHtcbiAgY29uc3QgZ29vZDogc3RyaW5nW10gPSBbXVxuICBjb25zdCBiYWQ6IHN0cmluZ1tdID0gW11cblxuICAvLyBGaW5kIGNvZGUgYmxvY2tzIGFmdGVyIFwiIyMjIEdvb2RcIiBvciBcIiMjIyBCYWRcIiBoZWFkZXJzXG4gIGNvbnN0IGdvb2RNYXRjaCA9IGNvbnRlbnQubWF0Y2goLyMjIyBHb29kXFxzKlxcbmBgYFtcXHNcXFNdKj9gYGAvZylcbiAgY29uc3QgYmFkTWF0Y2ggPSBjb250ZW50Lm1hdGNoKC8jIyMgQmFkXFxzKlxcbmBgYFtcXHNcXFNdKj9gYGAvZylcblxuICBpZiAoZ29vZE1hdGNoKSB7XG4gICAgZm9yIChjb25zdCBtYXRjaCBvZiBnb29kTWF0Y2gpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBtYXRjaC5yZXBsYWNlKC8jIyMgR29vZFxccypcXG4vLCAnJykudHJpbSgpXG4gICAgICBnb29kLnB1c2goY29kZSlcbiAgICB9XG4gIH1cblxuICBpZiAoYmFkTWF0Y2gpIHtcbiAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIGJhZE1hdGNoKSB7XG4gICAgICBjb25zdCBjb2RlID0gbWF0Y2gucmVwbGFjZSgvIyMjIEJhZFxccypcXG4vLCAnJykudHJpbSgpXG4gICAgICBiYWQucHVzaChjb2RlKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGdvb2QsIGJhZCB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgLmN1cnNvcnJ1bGVzIGNvbnRlbnQgZnJvbSBDYW5vblxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZUN1cnNvcnJ1bGVzKCk6IHN0cmluZyB7XG4gIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtdXG5cbiAgLy8gSGVhZGVyXG4gIGxpbmVzLnB1c2goYCMgR2FsbG9wIENhbm9uIHYke3ZlcnNpb259IC0gQUkgUnVsZXNgKVxuICBsaW5lcy5wdXNoKCcnKVxuICBsaW5lcy5wdXNoKCdUaGlzIGZpbGUgaXMgYXV0by1nZW5lcmF0ZWQgZnJvbSBAZ2FsbG9wLnNvZnR3YXJlL2Nhbm9uLiBEbyBub3QgZWRpdCBtYW51YWxseS4nKVxuICBsaW5lcy5wdXNoKCdSZWdlbmVyYXRlIHdpdGg6IG5wbSBydW4gZ2VuZXJhdGU6YWktcnVsZXMnKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIC8vIFRlY2ggc3RhY2sgKENhbm9uLWNvbXBhdGlibGUgdGVtcGxhdGVzKVxuICBsaW5lcy5wdXNoKCcjIyBUZWNoIFN0YWNrJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnLSBOZXh0LmpzIDE2IHdpdGggQXBwIFJvdXRlcicpXG4gIGxpbmVzLnB1c2goJy0gUmVhY3QgMTknKVxuICBsaW5lcy5wdXNoKCctIFR5cGVTY3JpcHQnKVxuICBsaW5lcy5wdXNoKCctIFRhaWx3aW5kIENTUyB2NCcpXG4gIGxpbmVzLnB1c2goJy0gY2xzeCBmb3IgY29uZGl0aW9uYWwgY2xhc3MgbmFtZXMnKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIC8vIEVuZm9yY2VkIHBhdHRlcm5zIChFU0xpbnQgcnVsZXMpXG4gIGxpbmVzLnB1c2goJyMjIEVuZm9yY2VkIFBhdHRlcm5zIChFU0xpbnQpJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnVGhlc2UgcGF0dGVybnMgYXJlIGVuZm9yY2VkIGJ5IGBAZ2FsbG9wLnNvZnR3YXJlL2Nhbm9uL2VzbGludGAuIFZpb2xhdGlvbnMgd2lsbCBiZSBmbGFnZ2VkLicpXG4gIGxpbmVzLnB1c2goJycpXG5cbiAgY29uc3QgZW5mb3JjZWRQYXR0ZXJucyA9IHBhdHRlcm5zLmZpbHRlcihwID0+IHAuZW5mb3JjZW1lbnQgPT09ICdlc2xpbnQnICYmIHAucnVsZSlcbiAgZm9yIChjb25zdCBwYXR0ZXJuIG9mIGVuZm9yY2VkUGF0dGVybnMpIHtcbiAgICBsaW5lcy5wdXNoKGAjIyMgJHtwYXR0ZXJuLmlkfTogJHtwYXR0ZXJuLnRpdGxlfWApXG4gICAgbGluZXMucHVzaCgnJylcbiAgICBsaW5lcy5wdXNoKHBhdHRlcm4uc3VtbWFyeSlcbiAgICBsaW5lcy5wdXNoKCcnKVxuICAgIGxpbmVzLnB1c2goYC0gKipFU0xpbnQgUnVsZToqKiBcXGAke3BhdHRlcm4ucnVsZX1cXGBgKVxuICAgIGxpbmVzLnB1c2goYC0gKipDYXRlZ29yeToqKiAke3BhdHRlcm4uY2F0ZWdvcnl9YClcbiAgICBsaW5lcy5wdXNoKCcnKVxuXG4gICAgLy8gVHJ5IHRvIHJlYWQgYW5kIGluY2x1ZGUgZXhhbXBsZXNcbiAgICBjb25zdCBjb250ZW50ID0gcmVhZFBhdHRlcm5GaWxlKHBhdHRlcm4uZmlsZSlcbiAgICBpZiAoY29udGVudCkge1xuICAgICAgY29uc3QgeyBnb29kLCBiYWQgfSA9IGV4dHJhY3RFeGFtcGxlcyhjb250ZW50KVxuICAgICAgaWYgKGJhZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxpbmVzLnB1c2goJyoqQmFkOioqJylcbiAgICAgICAgbGluZXMucHVzaCgnJylcbiAgICAgICAgbGluZXMucHVzaChiYWRbMF0pXG4gICAgICAgIGxpbmVzLnB1c2goJycpXG4gICAgICB9XG4gICAgICBpZiAoZ29vZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGxpbmVzLnB1c2goJyoqR29vZDoqKicpXG4gICAgICAgIGxpbmVzLnB1c2goJycpXG4gICAgICAgIGxpbmVzLnB1c2goZ29vZFswXSlcbiAgICAgICAgbGluZXMucHVzaCgnJylcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBEb2N1bWVudGF0aW9uIHBhdHRlcm5zXG4gIGxpbmVzLnB1c2goJyMjIERvY3VtZW50YXRpb24gUGF0dGVybnMnKVxuICBsaW5lcy5wdXNoKCcnKVxuICBsaW5lcy5wdXNoKCdUaGVzZSBwYXR0ZXJucyBhcmUgbm90IGVuZm9yY2VkIGJ5IEVTTGludCBidXQgc2hvdWxkIGJlIGZvbGxvd2VkLicpXG4gIGxpbmVzLnB1c2goJycpXG5cbiAgY29uc3QgZG9jUGF0dGVybnMgPSBwYXR0ZXJucy5maWx0ZXIocCA9PiBwLmVuZm9yY2VtZW50ID09PSAnZG9jdW1lbnRhdGlvbicpXG4gIGZvciAoY29uc3QgcGF0dGVybiBvZiBkb2NQYXR0ZXJucykge1xuICAgIGxpbmVzLnB1c2goYCMjIyAke3BhdHRlcm4uaWR9OiAke3BhdHRlcm4udGl0bGV9YClcbiAgICBsaW5lcy5wdXNoKCcnKVxuICAgIGxpbmVzLnB1c2gocGF0dGVybi5zdW1tYXJ5KVxuICAgIGxpbmVzLnB1c2goJycpXG4gIH1cblxuICAvLyBHdWFyYW50ZWVzXG4gIGxpbmVzLnB1c2goJyMjIENhbm9uIEd1YXJhbnRlZXMnKVxuICBsaW5lcy5wdXNoKCcnKVxuICBsaW5lcy5wdXNoKCdGb2xsb3dpbmcgdGhlc2UgcGF0dGVybnMgcHJvdmlkZXMgdGhlc2UgZ3VhcmFudGVlczonKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIGZvciAoY29uc3QgZ3VhcmFudGVlIG9mIGd1YXJhbnRlZXMpIHtcbiAgICBsaW5lcy5wdXNoKGAtICoqJHtndWFyYW50ZWUubmFtZX0qKiAoJHtndWFyYW50ZWUuaWR9KTogUGF0dGVybnMgJHtndWFyYW50ZWUucGF0dGVybnMuam9pbignLCAnKX1gKVxuICB9XG4gIGxpbmVzLnB1c2goJycpXG5cbiAgLy8gUXVpY2sgcmVmZXJlbmNlIGZvciBjb21wb25lbnRzXG4gIGxpbmVzLnB1c2goJyMjIENvbXBvbmVudCBRdWljayBSZWZlcmVuY2UnKVxuICBsaW5lcy5wdXNoKCcnKVxuICBsaW5lcy5wdXNoKCcjIyMgVHlwb2dyYXBoeScpXG4gIGxpbmVzLnB1c2goJy0gYEhlYWRpbmdgIC0gcHJvcHM6IGBhc2AsIGBjb2xvcmAsIGBtYXJnaW5gLCBgZm9udFNpemVgLCBgZm9udFdlaWdodGAsIGB0ZXh0QWxpZ25gJylcbiAgbGluZXMucHVzaCgnLSBgUGFyYWdyYXBoYCAtIHByb3BzOiBgY29sb3JgLCBgbWFyZ2luYCwgYGZvbnRTaXplYCwgYGxpbmVIZWlnaHRgLCBgdGV4dEFsaWduYCcpXG4gIGxpbmVzLnB1c2goJy0gYFNwYW5gIC0gcHJvcHM6IGBjb2xvcmAsIGBtYXJnaW5gLCBgZm9udFNpemVgIChpbmxpbmUgdGV4dCwgbWItMCBkZWZhdWx0KScpXG4gIGxpbmVzLnB1c2goJy0gYExhYmVsYCAtIHByb3BzOiBgY29sb3JgLCBgbWFyZ2luYCwgYGZvbnRTaXplYCwgYGZvbnRXZWlnaHRgLCBgdGV4dEFsaWduYCcpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJyMjIyBMYXlvdXQnKVxuICBsaW5lcy5wdXNoKCctIGBTZWN0aW9uYCAtIHNlbWFudGljIHNlY3Rpb24gd3JhcHBlcicpXG4gIGxpbmVzLnB1c2goJy0gYENvbHVtbnNgIC0gZ3JpZCBsYXlvdXQsIHByb3BzOiBgY29sc2AsIGBnYXBgLCBgYWxpZ25gJylcbiAgbGluZXMucHVzaCgnLSBgQ29sdW1uYCAtIGNvbHVtbiBjaGlsZCcpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJyMjIyBJbnRlcmFjdGl2ZScpXG4gIGxpbmVzLnB1c2goJy0gYEJ1dHRvbmAgLSBwcm9wczogYGhyZWZgLCBgdmFyaWFudGAsIGBpY29uYCwgYGljb25QbGFjZW1lbnRgLCBgbWFyZ2luYCcpXG4gIGxpbmVzLnB1c2goJy0gYEljb25gIC0gSWNvbmlmeSBpY29uIHdyYXBwZXInKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIC8vIERvIE5PVCBzZWN0aW9uXG4gIGxpbmVzLnB1c2goJyMjIERvIE5PVCcpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJy0gVXNlIGBcXCd1c2UgY2xpZW50XFwnYCBpbiBibG9ja3MgLSBleHRyYWN0IHRvIGNvbXBvbmVudHMnKVxuICBsaW5lcy5wdXNoKCctIFVzZSByYXcgYDxwPmAgb3IgYDxzcGFuPmAgLSB1c2UgUGFyYWdyYXBoL1NwYW4gY29tcG9uZW50cycpXG4gIGxpbmVzLnB1c2goJy0gVXNlIGNsYXNzTmFtZSBmb3IgbWFyZ2luL2NvbG9yL2ZvbnRTaXplIHdoZW4gY29tcG9uZW50IGhhcyBwcm9wcycpXG4gIGxpbmVzLnB1c2goJy0gVXNlIENvbnRhaW5lciBpbnNpZGUgU2VjdGlvbiAtIFNlY3Rpb24gYWxyZWFkeSBwcm92aWRlcyBjb250YWlubWVudCcpXG4gIGxpbmVzLnB1c2goJy0gVXNlIGBjbGFzc25hbWVzYCBwYWNrYWdlIC0gdXNlIGBjbHN4YCBpbnN0ZWFkJylcbiAgbGluZXMucHVzaCgnLSBVc2UgaW5saW5lIHN0eWxlcyBmb3IgaG92ZXIgc3RhdGVzIC0gdXNlIFRhaWx3aW5kIGNsYXNzZXMnKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIC8vIEZpbGUgJiBGb2xkZXIgQXV0aG9yaXR5IHNlY3Rpb25cbiAgbGluZXMucHVzaCgnIyMgRmlsZSAmIEZvbGRlciBBdXRob3JpdHknKVxuICBsaW5lcy5wdXNoKCcnKVxuICBsaW5lcy5wdXNoKCdUaGVzZSBydWxlcyBnb3Zlcm4gd2hhdCBBSSBpcyBhbGxvd2VkIGFuZCBmb3JiaWRkZW4gdG8gZG8gd2hlbiBjcmVhdGluZywgbW92aW5nLCBvciBtb2RpZnlpbmcgZmlsZXMgYW5kIGZvbGRlcnMuJylcbiAgbGluZXMucHVzaCgnJylcblxuICBsaW5lcy5wdXNoKCcjIyMgRGVmaW5lZCBgL3NyY2AgU3RydWN0dXJlJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnYGBgJylcbiAgbGluZXMucHVzaCgnc3JjLycpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCBhcHAvICAgICAgICAgICMgUm91dGVzLCBsYXlvdXRzLCBtZXRhZGF0YSAoTmV4dC5qcyBBcHAgUm91dGVyKScpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCBibG9ja3MvICAgICAgICMgUGFnZS1sZXZlbCBjb250ZW50IHNlY3Rpb25zJylcbiAgbGluZXMucHVzaCgn4pSc4pSA4pSAIGJsb2cvICAgICAgICAgIyBCbG9nIGNvbnRlbnQgKGFyY2hpdmUgY29udGVudCB0eXBlKScpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCBjb21wb25lbnRzLyAgICMgUmV1c2FibGUgVUkgcHJpbWl0aXZlcycpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCBob29rcy8gICAgICAgICMgQ3VzdG9tIFJlYWN0IGhvb2tzJylcbiAgbGluZXMucHVzaCgn4pSc4pSA4pSAIHN0eWxlcy8gICAgICAgIyBDU1MsIFRhaWx3aW5kLCBmb250cycpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCB0ZW1wbGF0ZS8gICAgICMgVGVtcGxhdGUtbGV2ZWwgY29tcG9uZW50cycpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCB0b29scy8gICAgICAgICMgVXRpbGl0eSB0b29scycpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCB0eXBlcy8gICAgICAgICMgVHlwZVNjcmlwdCB0eXBlcycpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCB1dGlscy8gICAgICAgICMgVXRpbGl0eSBmdW5jdGlvbnMnKVxuICBsaW5lcy5wdXNoKCfilJTilIDilIAgc3RhdGUudHMgICAgICAjIEdsb2JhbCBzdGF0ZScpXG4gIGxpbmVzLnB1c2goJ2BgYCcpXG4gIGxpbmVzLnB1c2goJycpXG5cbiAgbGluZXMucHVzaCgnIyMjIEFwcCBSb3V0ZXIgU3RydWN0dXJlJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnUm91dGVzIG11c3QgdXNlIE5leHQuanMgcm91dGUgZ3JvdXBzLiBBdCBtaW5pbXVtLCBgKGRlZmF1bHQpYCBtdXN0IGV4aXN0OicpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJ2BgYCcpXG4gIGxpbmVzLnB1c2goJ3NyYy9hcHAvJylcbiAgbGluZXMucHVzaCgn4pSc4pSA4pSAIChkZWZhdWx0KS8gICAgICAgICMgUmVxdWlyZWQgLSBkZWZhdWx0IGxheW91dCBncm91cCcpXG4gIGxpbmVzLnB1c2goJ+KUgiAgIOKUnOKUgOKUgCBsYXlvdXQudHN4JylcbiAgbGluZXMucHVzaCgn4pSCICAg4pSU4pSA4pSAIHtyb3V0ZXN9LycpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCAoaGVybykvICAgICAgICAgICAjIE9wdGlvbmFsIC0gaGVybyBsYXlvdXQgdmFyaWFudCcpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCBhcGkvICAgICAgICAgICAgICAjIEFQSSByb3V0ZXMgKGV4Y2VwdGlvbiAtIG5vIGdyb3VwaW5nKScpXG4gIGxpbmVzLnB1c2goJ+KUnOKUgOKUgCBsYXlvdXQudHN4ICAgICAgICAjIFJvb3QgbGF5b3V0JylcbiAgbGluZXMucHVzaCgn4pSU4pSA4pSAIG1ldGFkYXRhLnRzeCAgICAgICMgU2hhcmVkIG1ldGFkYXRhJylcbiAgbGluZXMucHVzaCgnYGBgJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnLSBBbGwgcGFnZSByb3V0ZXMgbXVzdCBiZSBpbnNpZGUgYSByb3V0ZSBncm91cCAocGFyZW50aGVzZXMgZm9sZGVyKScpXG4gIGxpbmVzLnB1c2goJy0gTmV2ZXIgY3JlYXRlIHJvdXRlcyBkaXJlY3RseSB1bmRlciBgc3JjL2FwcC9gIChleGNlcHQgYGFwaS9gLCByb290IGZpbGVzKScpXG4gIGxpbmVzLnB1c2goJy0gTmV3IHJvdXRlIGdyb3VwcyBhcmUgYWxsb3dlZCBmcmVlbHkgd2hlbiBhIG5ldyBsYXlvdXQgdmFyaWFudCBpcyBuZWVkZWQnKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIGxpbmVzLnB1c2goJyMjIyBGaWxlIFN0cnVjdHVyZSBSdWxlcycpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJyoqQmxvY2tzOioqJylcbiAgbGluZXMucHVzaCgnLSBBbHdheXMgc2luZ2xlIGZpbGVzIGRpcmVjdGx5IGluIGBzcmMvYmxvY2tzL2AnKVxuICBsaW5lcy5wdXNoKCctIE5ldmVyIGNyZWF0ZSBmb2xkZXJzIGluc2lkZSBgc3JjL2Jsb2Nrcy9gJylcbiAgbGluZXMucHVzaCgnLSBFeGFtcGxlOiBgc3JjL2Jsb2Nrcy9oZXJvLTEudHN4YCwgYHNyYy9ibG9ja3MvdGVzdGltb25pYWwtMy50c3hgJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnKipDb21wb25lbnRzOioqJylcbiAgbGluZXMucHVzaCgnLSBTaW1wbGUgY29tcG9uZW50czogU2luZ2xlIGZpbGUgaW4gYHNyYy9jb21wb25lbnRzL2AnKVxuICBsaW5lcy5wdXNoKCctIENvbXBsZXggY29tcG9uZW50czogRm9sZGVyIHdpdGggYGluZGV4LnRzeGAnKVxuICBsaW5lcy5wdXNoKCctIFVzZSBmb2xkZXJzIHdoZW4gY29tcG9uZW50IGhhcyBtdWx0aXBsZSBzdWItZmlsZXMnKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIGxpbmVzLnB1c2goJyMjIyBETyAtIFdoYXQgQUkgSVMgQWxsb3dlZCBUbyBEbycpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJy0gQ3JlYXRlIGZpbGVzIG9ubHkgaW5zaWRlIGV4aXN0aW5nIENhbm9uLWRlZmluZWQgem9uZXMnKVxuICBsaW5lcy5wdXNoKCctIFBsYWNlIG5ldyBmaWxlcyBpbiB0aGUgem9uZSB0aGF0IG1hdGNoZXMgdGhlaXIgYXJjaGl0ZWN0dXJhbCByb2xlJylcbiAgbGluZXMucHVzaCgnLSBGb2xsb3cgZXhpc3RpbmcgZm9sZGVyIGNvbnZlbnRpb25zIHdpdGhpbiBhIHpvbmUnKVxuICBsaW5lcy5wdXNoKCctIFJldXNlIGV4aXN0aW5nIGZvbGRlcnMgd2hlbiBwb3NzaWJsZScpXG4gIGxpbmVzLnB1c2goJy0gQ3JlYXRlIG5ldyByb3V0ZSBncm91cHMgaW4gYHNyYy9hcHAvYCB3aGVuIG5ldyBsYXlvdXRzIGFyZSBuZWVkZWQnKVxuICBsaW5lcy5wdXNoKCctIENyZWF0ZSBuZXcgYXJjaGl2ZSBjb250ZW50IGZvbGRlcnMgKGxpa2UgYGJsb2cvYCwgYHBvcnRmb2xpby9gKSBpbiBgL3NyY2AnKVxuICBsaW5lcy5wdXNoKCctIENyZWF0ZSBkb3RmaWxlcy9kaXJlY3RvcmllcyBhdCBwcm9qZWN0IHJvb3QgKGAuZ2l0aHViL2AsIGAuY3Vyc29yL2AsIGV0Yy4pJylcbiAgbGluZXMucHVzaCgnLSBBc2sgZm9yIGNvbmZpcm1hdGlvbiBpZiB0aGUgY29ycmVjdCB6b25lIGlzIGFtYmlndW91cycpXG4gIGxpbmVzLnB1c2goJycpXG5cbiAgbGluZXMucHVzaCgnIyMjIERPIE5PVCAtIFdoYXQgQUkgSXMgRm9yYmlkZGVuIFRvIERvJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnLSBDcmVhdGUgbmV3IHRvcC1sZXZlbCBkaXJlY3RvcmllcyAoZXhjZXB0IGRvdGZpbGVzKScpXG4gIGxpbmVzLnB1c2goJy0gQ3JlYXRlIG5ldyBmb2xkZXJzIGluIGAvc3JjYCAoZXhjZXB0IGFyY2hpdmUgY29udGVudCBvciByb3V0ZSBncm91cHMpJylcbiAgbGluZXMucHVzaCgnLSBQbGFjZSBmaWxlcyBvdXRzaWRlIENhbm9uLWRlZmluZWQgem9uZXMnKVxuICBsaW5lcy5wdXNoKCctIE1peCByZXNwb25zaWJpbGl0aWVzIGFjcm9zcyB6b25lcyAoY29tcG9uZW50cyBpbXBvcnRpbmcgYmxvY2tzLCBldGMuKScpXG4gIGxpbmVzLnB1c2goJy0gUmVvcmdhbml6ZSBvciBtb3ZlIGZvbGRlcnMgd2l0aG91dCBleHBsaWNpdCBpbnN0cnVjdGlvbicpXG4gIGxpbmVzLnB1c2goJy0gSW52ZW50IG5ldyBvcmdhbml6YXRpb25hbCBjb252ZW50aW9ucycpXG4gIGxpbmVzLnB1c2goJy0gQ3JlYXRlIHBsYWNlaG9sZGVyIG9yIHNwZWN1bGF0aXZlIGZpbGVzJylcbiAgbGluZXMucHVzaCgnLSBJbXBvcnQgZnJvbSBgX3NjcmlwdHMvYCBvciBgX2RhdGEvYCBpbiBydW50aW1lIGNvZGUnKVxuICBsaW5lcy5wdXNoKCctIE1hbnVhbGx5IGVkaXQgZmlsZXMgaW4gYF9kYXRhL2AgKGdlbmVyYXRlZCBvbmx5KScpXG4gIGxpbmVzLnB1c2goJycpXG5cbiAgLy8gUG9zdC1lZGl0IHZlcmlmaWNhdGlvblxuICBsaW5lcy5wdXNoKCcjIyBQb3N0LUVkaXQgVmVyaWZpY2F0aW9uJylcbiAgbGluZXMucHVzaCgnJylcbiAgbGluZXMucHVzaCgnQWZ0ZXIgZWRpdGluZyBmaWxlczonKVxuICBsaW5lcy5wdXNoKCcxLiBSdW4gYG5wbSBydW4gbGludGAgdG8gY2hlY2sgZm9yIGVycm9ycycpXG4gIGxpbmVzLnB1c2goJzIuIEZpeCBhbnkgdmlvbGF0aW9ucyBiZWZvcmUgY29tbWl0dGluZycpXG4gIGxpbmVzLnB1c2goJycpXG4gIGxpbmVzLnB1c2goJ05vdGU6IE9ubHkgbGludCBmaWxlcyB5b3UgZWRpdGVkLCBub3QgdGhlIGVudGlyZSBjb2RlYmFzZS4nKVxuICBsaW5lcy5wdXNoKCcnKVxuXG4gIHJldHVybiBsaW5lcy5qb2luKCdcXG4nKVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGUob3B0aW9uczogR2VuZXJhdGVPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGNvbnRlbnQgPSBnZW5lcmF0ZUN1cnNvcnJ1bGVzKClcblxuICBpZiAob3B0aW9ucy5vdXRwdXQgPT09ICctJykge1xuICAgIC8vIE91dHB1dCB0byBzdGRvdXRcbiAgICBjb25zb2xlLmxvZyhjb250ZW50KVxuICB9IGVsc2Uge1xuICAgIC8vIFdyaXRlIHRvIGZpbGVcbiAgICBjb25zdCBvdXRwdXRQYXRoID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIG9wdGlvbnMub3V0cHV0KVxuICAgIGZzLndyaXRlRmlsZVN5bmMob3V0cHV0UGF0aCwgY29udGVudCwgJ3V0Zi04JylcbiAgICBjb25zb2xlLmxvZyhg4pyTIEdlbmVyYXRlZCAke29wdGlvbnMub3V0cHV0fSBmcm9tIENhbm9uIHYke3ZlcnNpb259YClcbiAgICBjb25zb2xlLmxvZyhgICAke3BhdHRlcm5zLmxlbmd0aH0gcGF0dGVybnMsICR7Z3VhcmFudGVlcy5sZW5ndGh9IGd1YXJhbnRlZXNgKVxuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
// Allowed top-level directories (non-dotfiles)
|
|
4
|
+
const ALLOWED_TOP_LEVEL = [
|
|
5
|
+
'src',
|
|
6
|
+
'public',
|
|
7
|
+
'_scripts',
|
|
8
|
+
'_data',
|
|
9
|
+
'_docs',
|
|
10
|
+
'node_modules',
|
|
11
|
+
];
|
|
12
|
+
// Allowed folders directly under /src
|
|
13
|
+
const ALLOWED_SRC_FOLDERS = [
|
|
14
|
+
'app',
|
|
15
|
+
'blocks',
|
|
16
|
+
'blog',
|
|
17
|
+
'components',
|
|
18
|
+
'hooks',
|
|
19
|
+
'styles',
|
|
20
|
+
'template',
|
|
21
|
+
'tools',
|
|
22
|
+
'types',
|
|
23
|
+
'utils',
|
|
24
|
+
];
|
|
25
|
+
// Files allowed at top level
|
|
26
|
+
const ALLOWED_TOP_LEVEL_FILES = [
|
|
27
|
+
'package.json',
|
|
28
|
+
'package-lock.json',
|
|
29
|
+
'tsconfig.json',
|
|
30
|
+
'next.config.mjs',
|
|
31
|
+
'next.config.js',
|
|
32
|
+
'next-env.d.ts',
|
|
33
|
+
'eslint.config.mjs',
|
|
34
|
+
'eslint.config.js',
|
|
35
|
+
'.eslintrc.js',
|
|
36
|
+
'.eslintrc.json',
|
|
37
|
+
'postcss.config.js',
|
|
38
|
+
'tailwind.config.js',
|
|
39
|
+
'tailwind.config.ts',
|
|
40
|
+
'README.md',
|
|
41
|
+
'LICENSE',
|
|
42
|
+
'CHANGELOG.md',
|
|
43
|
+
'.gitignore',
|
|
44
|
+
'.cursorrules',
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Check if a path is a dotfile or dotfolder
|
|
48
|
+
*/
|
|
49
|
+
function isDotfile(name) {
|
|
50
|
+
return name.startsWith('.');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if a path is an archive content folder (allowed new folders in /src)
|
|
54
|
+
*/
|
|
55
|
+
function isArchiveContentFolder(name) {
|
|
56
|
+
// Archive folders typically have plural names for content collections
|
|
57
|
+
// We allow any folder that could reasonably be archive content
|
|
58
|
+
// This is a heuristic - we check if it looks like a content collection
|
|
59
|
+
return !ALLOWED_SRC_FOLDERS.includes(name);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Validate project structure
|
|
63
|
+
*/
|
|
64
|
+
export async function validate(projectPath, options) {
|
|
65
|
+
const violations = [];
|
|
66
|
+
const absolutePath = path.resolve(process.cwd(), projectPath);
|
|
67
|
+
if (!fs.existsSync(absolutePath)) {
|
|
68
|
+
console.error(`Path does not exist: ${projectPath}`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
// Check top-level directories
|
|
72
|
+
const topLevelItems = fs.readdirSync(absolutePath);
|
|
73
|
+
for (const item of topLevelItems) {
|
|
74
|
+
const itemPath = path.join(absolutePath, item);
|
|
75
|
+
const stat = fs.statSync(itemPath);
|
|
76
|
+
if (stat.isDirectory()) {
|
|
77
|
+
// Dotfolders are exempt
|
|
78
|
+
if (isDotfile(item)) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// Check if it's an allowed top-level directory
|
|
82
|
+
if (!ALLOWED_TOP_LEVEL.includes(item)) {
|
|
83
|
+
violations.push({
|
|
84
|
+
type: 'invalid-top-level',
|
|
85
|
+
path: item,
|
|
86
|
+
message: `Invalid top-level directory: ${item}. Allowed: ${ALLOWED_TOP_LEVEL.join(', ')} (dotfolders exempt)`,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// It's a file - check if it's allowed at top level
|
|
92
|
+
if (!isDotfile(item) && !ALLOWED_TOP_LEVEL_FILES.includes(item)) {
|
|
93
|
+
// Allow common config file patterns
|
|
94
|
+
const isConfigFile = item.endsWith('.config.js') ||
|
|
95
|
+
item.endsWith('.config.mjs') ||
|
|
96
|
+
item.endsWith('.config.ts') ||
|
|
97
|
+
item.endsWith('.json') ||
|
|
98
|
+
item.endsWith('.md') ||
|
|
99
|
+
item.endsWith('.sh');
|
|
100
|
+
if (!isConfigFile) {
|
|
101
|
+
violations.push({
|
|
102
|
+
type: 'orphan-file',
|
|
103
|
+
path: item,
|
|
104
|
+
message: `Orphan file at project root: ${item}. Files should be in defined zones.`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Check /src folder structure
|
|
111
|
+
const srcPath = path.join(absolutePath, 'src');
|
|
112
|
+
if (fs.existsSync(srcPath)) {
|
|
113
|
+
const srcItems = fs.readdirSync(srcPath);
|
|
114
|
+
for (const item of srcItems) {
|
|
115
|
+
const itemPath = path.join(srcPath, item);
|
|
116
|
+
const stat = fs.statSync(itemPath);
|
|
117
|
+
if (stat.isDirectory()) {
|
|
118
|
+
// Check if it's an allowed /src folder
|
|
119
|
+
if (!ALLOWED_SRC_FOLDERS.includes(item) &&
|
|
120
|
+
!isArchiveContentFolder(item)) {
|
|
121
|
+
violations.push({
|
|
122
|
+
type: 'invalid-src-folder',
|
|
123
|
+
path: `src/${item}`,
|
|
124
|
+
message: `Invalid folder in /src: ${item}. Allowed: ${ALLOWED_SRC_FOLDERS.join(', ')} or archive content folders`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Check that src/app has route groups
|
|
130
|
+
const appPath = path.join(srcPath, 'app');
|
|
131
|
+
if (fs.existsSync(appPath)) {
|
|
132
|
+
const appItems = fs.readdirSync(appPath);
|
|
133
|
+
const hasDefaultGroup = appItems.some((item) => item === '(default)' || item.startsWith('('));
|
|
134
|
+
if (!hasDefaultGroup) {
|
|
135
|
+
violations.push({
|
|
136
|
+
type: 'invalid-src-folder',
|
|
137
|
+
path: 'src/app',
|
|
138
|
+
message: 'src/app should have at least one route group folder (e.g., (default)/)',
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Output results
|
|
144
|
+
if (options.json) {
|
|
145
|
+
console.log(JSON.stringify({
|
|
146
|
+
valid: violations.length === 0,
|
|
147
|
+
violations,
|
|
148
|
+
}, null, 2));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
if (violations.length === 0) {
|
|
152
|
+
console.log('✓ Project structure is valid');
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
console.log(`Found ${violations.length} violation(s):\n`);
|
|
156
|
+
for (const v of violations) {
|
|
157
|
+
console.log(` ✗ ${v.message}`);
|
|
158
|
+
}
|
|
159
|
+
console.log('');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Exit with error code if strict mode and violations found
|
|
163
|
+
if (options.strict && violations.length > 0) {
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2NvbW1hbmRzL3ZhbGlkYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFBO0FBQ3hCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBYTVCLCtDQUErQztBQUMvQyxNQUFNLGlCQUFpQixHQUFHO0lBQ3hCLEtBQUs7SUFDTCxRQUFRO0lBQ1IsVUFBVTtJQUNWLE9BQU87SUFDUCxPQUFPO0lBQ1AsY0FBYztDQUNmLENBQUE7QUFFRCxzQ0FBc0M7QUFDdEMsTUFBTSxtQkFBbUIsR0FBRztJQUMxQixLQUFLO0lBQ0wsUUFBUTtJQUNSLE1BQU07SUFDTixZQUFZO0lBQ1osT0FBTztJQUNQLFFBQVE7SUFDUixVQUFVO0lBQ1YsT0FBTztJQUNQLE9BQU87SUFDUCxPQUFPO0NBQ1IsQ0FBQTtBQUVELDZCQUE2QjtBQUM3QixNQUFNLHVCQUF1QixHQUFHO0lBQzlCLGNBQWM7SUFDZCxtQkFBbUI7SUFDbkIsZUFBZTtJQUNmLGlCQUFpQjtJQUNqQixnQkFBZ0I7SUFDaEIsZUFBZTtJQUNmLG1CQUFtQjtJQUNuQixrQkFBa0I7SUFDbEIsY0FBYztJQUNkLGdCQUFnQjtJQUNoQixtQkFBbUI7SUFDbkIsb0JBQW9CO0lBQ3BCLG9CQUFvQjtJQUNwQixXQUFXO0lBQ1gsU0FBUztJQUNULGNBQWM7SUFDZCxZQUFZO0lBQ1osY0FBYztDQUNmLENBQUE7QUFFRDs7R0FFRztBQUNILFNBQVMsU0FBUyxDQUFDLElBQVk7SUFDN0IsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQzdCLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsc0JBQXNCLENBQUMsSUFBWTtJQUMxQyxzRUFBc0U7SUFDdEUsK0RBQStEO0lBQy9ELHVFQUF1RTtJQUN2RSxPQUFPLENBQUMsbUJBQW1CLENBQUMs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UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELGlCQUFpQjtJQUNqQixJQUFJLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNqQixPQUFPLENBQUMsR0FBRyxDQUNULElBQUksQ0FBQyxTQUFTLENBQ1o7WUFDRSxLQUFLLEVBQUUsVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQzlCLFVBQVU7U0FDWCxFQUNELElBQUksRUFDSixDQUFDLENBQ0YsQ0FDRixDQUFBO0lBQ0gsQ0FBQztTQUFNLENBQUM7UUFDTixJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDNUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFBO1FBQzdDLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLFVBQVUsQ0FBQyxNQUFNLGtCQUFrQixDQUFDLENBQUE7WUFDekQsS0FBSyxNQUFNLENBQUMsSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDM0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO1lBQ2pDLENBQUM7WUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ2pCLENBQUM7SUFDSCxDQUFDO0lBRUQsMkRBQTJEO0lBQzNELElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzVDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDakIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcydcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCdcblxuaW50ZXJmYWNlIFZhbGlkYXRlT3B0aW9ucyB7XG4gIHN0cmljdDogYm9vbGVhblxuICBqc29uOiBib29sZWFuXG59XG5cbmludGVyZmFjZSBWaW9sYXRpb24ge1xuICB0eXBlOiAnb3JwaGFuLWZpbGUnIHwgJ2ludmFsaWQtdG9wLWxldmVsJyB8ICdpbnZhbGlkLXNyYy1mb2xkZXInXG4gIHBhdGg6IHN0cmluZ1xuICBtZXNzYWdlOiBzdHJpbmdcbn1cblxuLy8gQWxsb3dlZCB0b3AtbGV2ZWwgZGlyZWN0b3JpZXMgKG5vbi1kb3RmaWxlcylcbmNvbnN0IEFMTE9XRURfVE9QX0xFVkVMID0gW1xuICAnc3JjJyxcbiAgJ3B1YmxpYycsXG4gICdfc2NyaXB0cycsXG4gICdfZGF0YScsXG4gICdfZG9jcycsXG4gICdub2RlX21vZHVsZXMnLFxuXVxuXG4vLyBBbGxvd2VkIGZvbGRlcnMgZGlyZWN0bHkgdW5kZXIgL3NyY1xuY29uc3QgQUxMT1dFRF9TUkNfRk9MREVSUyA9IFtcbiAgJ2FwcCcsXG4gICdibG9ja3MnLFxuICAnYmxvZycsXG4gICdjb21wb25lbnRzJyxcbiAgJ2hvb2tzJyxcbiAgJ3N0eWxlcycsXG4gICd0ZW1wbGF0ZScsXG4gICd0b29scycsXG4gICd0eXBlcycsXG4gICd1dGlscycsXG5dXG5cbi8vIEZpbGVzIGFsbG93ZWQgYXQgdG9wIGxldmVsXG5jb25zdCBBTExPV0VEX1RPUF9MRVZFTF9GSUxFUyA9IFtcbiAgJ3BhY2thZ2UuanNvbicsXG4gICdwYWNrYWdlLWxvY2suanNvbicsXG4gICd0c2NvbmZpZy5qc29uJyxcbiAgJ25leHQuY29uZmlnLm1qcycsXG4gICduZXh0LmNvbmZpZy5qcycsXG4gICduZXh0LWVudi5kLnRzJyxcbiAgJ2VzbGludC5jb25maWcubWpzJyxcbiAgJ2VzbGludC5jb25maWcuanMnLFxuICAnLmVzbGludHJjLmpzJyxcbiAgJy5lc2xpbnRyYy5qc29uJyxcbiAgJ3Bvc3Rjc3MuY29uZmlnLmpzJyxcbiAgJ3RhaWx3aW5kLmNvbmZpZy5qcycsXG4gICd0YWlsd2luZC5jb25maWcudHMnLFxuICAnUkVBRE1FLm1kJyxcbiAgJ0xJQ0VOU0UnLFxuICAnQ0hBTkdFTE9HLm1kJyxcbiAgJy5naXRpZ25vcmUnLFxuICAnLmN1cnNvcnJ1bGVzJyxcbl1cblxuLyoqXG4gKiBDaGVjayBpZiBhIHBhdGggaXMgYSBkb3RmaWxlIG9yIGRvdGZvbGRlclxuICovXG5mdW5jdGlvbiBpc0RvdGZpbGUobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBuYW1lLnN0YXJ0c1dpdGgoJy4nKVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgcGF0aCBpcyBhbiBhcmNoaXZlIGNvbnRlbnQgZm9sZGVyIChhbGxvd2VkIG5ldyBmb2xkZXJzIGluIC9zcmMpXG4gKi9cbmZ1bmN0aW9uIGlzQXJjaGl2ZUNvbnRlbnRGb2xkZXIobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIC8vIEFyY2hpdmUgZm9sZGVycyB0eXBpY2FsbHkgaGF2ZSBwbHVyYWwgbmFtZXMgZm9yIGNvbnRlbnQgY29sbGVjdGlvbnNcbiAgLy8gV2UgYWxsb3cgYW55IGZvbGRlciB0aGF0IGNvdWxkIHJlYXNvbmFibHkgYmUgYXJjaGl2ZSBjb250ZW50XG4gIC8vIFRoaXMgaXMgYSBoZXVyaXN0aWMgLSB3ZSBjaGVjayBpZiBpdCBsb29rcyBsaWtlIGEgY29udGVudCBjb2xsZWN0aW9uXG4gIHJldHVybiAhQUxMT1dFRF9TUkNfRk9MREVSUy5pbmNsdWRlcyhuYW1lKVxufVxuXG4vKipcbiAqIFZhbGlkYXRlIHByb2plY3Qgc3RydWN0dXJlXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB2YWxpZGF0ZShcbiAgcHJvamVjdFBhdGg6IHN0cmluZyxcbiAgb3B0aW9uczogVmFsaWRhdGVPcHRpb25zXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgdmlvbGF0aW9uczogVmlvbGF0aW9uW10gPSBbXVxuICBjb25zdCBhYnNvbHV0ZVBhdGggPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgcHJvamVjdFBhdGgpXG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKGFic29sdXRlUGF0aCkpIHtcbiAgICBjb25zb2xlLmVycm9yKGBQYXRoIGRvZXMgbm90IGV4aXN0OiAke3Byb2plY3RQYXRofWApXG4gICAgcHJvY2Vzcy5leGl0KDEpXG4gIH1cblxuICAvLyBDaGVjayB0b3AtbGV2ZWwgZGlyZWN0b3JpZXNcbiAgY29uc3QgdG9wTGV2ZWxJdGVtcyA9IGZzLnJlYWRkaXJTeW5jKGFic29sdXRlUGF0aClcbiAgZm9yIChjb25zdCBpdGVtIG9mIHRvcExldmVsSXRlbXMpIHtcbiAgICBjb25zdCBpdGVtUGF0aCA9IHBhdGguam9pbihhYnNvbHV0ZVBhdGgsIGl0ZW0pXG4gICAgY29uc3Qgc3RhdCA9IGZzLnN0YXRTeW5jKGl0ZW1QYXRoKVxuXG4gICAgaWYgKHN0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgLy8gRG90Zm9sZGVycyBhcmUgZXhlbXB0XG4gICAgICBpZiAoaXNEb3RmaWxlKGl0ZW0pKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGlmIGl0J3MgYW4gYWxsb3dlZCB0b3AtbGV2ZWwgZGlyZWN0b3J5XG4gICAgICBpZiAoIUFMTE9XRURfVE9QX0xFVkVMLmluY2x1ZGVzKGl0ZW0pKSB7XG4gICAgICAgIHZpb2xhdGlvbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ2ludmFsaWQtdG9wLWxldmVsJyxcbiAgICAgICAgICBwYXRoOiBpdGVtLFxuICAgICAgICAgIG1lc3NhZ2U6IGBJbnZhbGlkIHRvcC1sZXZlbCBkaXJlY3Rvcnk6ICR7aXRlbX0uIEFsbG93ZWQ6ICR7QUxMT1dFRF9UT1BfTEVWRUwuam9pbignLCAnKX0gKGRvdGZvbGRlcnMgZXhlbXB0KWAsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEl0J3MgYSBmaWxlIC0gY2hlY2sgaWYgaXQncyBhbGxvd2VkIGF0IHRvcCBsZXZlbFxuICAgICAgaWYgKCFpc0RvdGZpbGUoaXRlbSkgJiYgIUFMTE9XRURfVE9QX0xFVkVMX0ZJTEVTLmluY2x1ZGVzKGl0ZW0pKSB7XG4gICAgICAgIC8vIEFsbG93IGNvbW1vbiBjb25maWcgZmlsZSBwYXR0ZXJuc1xuICAgICAgICBjb25zdCBpc0NvbmZpZ0ZpbGUgPVxuICAgICAgICAgIGl0ZW0uZW5kc1dpdGgoJy5jb25maWcuanMnKSB8fFxuICAgICAgICAgIGl0ZW0uZW5kc1dpdGgoJy5jb25maWcubWpzJykgfHxcbiAgICAgICAgICBpdGVtLmVuZHNXaXRoKCcuY29uZmlnLnRzJykgfHxcbiAgICAgICAgICBpdGVtLmVuZHNXaXRoKCcuanNvbicpIHx8XG4gICAgICAgICAgaXRlbS5lbmRzV2l0aCgnLm1kJykgfHxcbiAgICAgICAgICBpdGVtLmVuZHNXaXRoKCcuc2gnKVxuXG4gICAgICAgIGlmICghaXNDb25maWdGaWxlKSB7XG4gICAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdvcnBoYW4tZmlsZScsXG4gICAgICAgICAgICBwYXRoOiBpdGVtLFxuICAgICAgICAgICAgbWVzc2FnZTogYE9ycGhhbiBmaWxlIGF0IHByb2plY3Qgcm9vdDogJHtpdGVtfS4gRmlsZXMgc2hvdWxkIGJlIGluIGRlZmluZWQgem9uZXMuYCxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgL3NyYyBmb2xkZXIgc3RydWN0dXJlXG4gIGNvbnN0IHNyY1BhdGggPSBwYXRoLmpvaW4oYWJzb2x1dGVQYXRoLCAnc3JjJylcbiAgaWYgKGZzLmV4aXN0c1N5bmMoc3JjUGF0aCkpIHtcbiAgICBjb25zdCBzcmNJdGVtcyA9IGZzLnJlYWRkaXJTeW5jKHNyY1BhdGgpXG4gICAgZm9yIChjb25zdCBpdGVtIG9mIHNyY0l0ZW1zKSB7XG4gICAgICBjb25zdCBpdGVtUGF0aCA9IHBhdGguam9pbihzcmNQYXRoLCBpdGVtKVxuICAgICAgY29uc3Qgc3RhdCA9IGZzLnN0YXRTeW5jKGl0ZW1QYXRoKVxuXG4gICAgICBpZiAoc3RhdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIGl0J3MgYW4gYWxsb3dlZCAvc3JjIGZvbGRlclxuICAgICAgICBpZiAoXG4gICAgICAgICAgIUFMTE9XRURfU1JDX0ZPTERFUlMuaW5jbHVkZXMoaXRlbSkgJiZcbiAgICAgICAgICAhaXNBcmNoaXZlQ29udGVudEZvbGRlcihpdGVtKVxuICAgICAgICApIHtcbiAgICAgICAgICB2aW9sYXRpb25zLnB1c2goe1xuICAgICAgICAgICAgdHlwZTogJ2ludmFsaWQtc3JjLWZvbGRlcicsXG4gICAgICAgICAgICBwYXRoOiBgc3JjLyR7aXRlbX1gLFxuICAgICAgICAgICAgbWVzc2FnZTogYEludmFsaWQgZm9sZGVyIGluIC9zcmM6ICR7aXRlbX0uIEFsbG93ZWQ6ICR7QUxMT1dFRF9TUkNfRk9MREVSUy5qb2luKCcsICcpfSBvciBhcmNoaXZlIGNvbnRlbnQgZm9sZGVyc2AsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENoZWNrIHRoYXQgc3JjL2FwcCBoYXMgcm91dGUgZ3JvdXBzXG4gICAgY29uc3QgYXBwUGF0aCA9IHBhdGguam9pbihzcmNQYXRoLCAnYXBwJylcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhhcHBQYXRoKSkge1xuICAgICAgY29uc3QgYXBwSXRlbXMgPSBmcy5yZWFkZGlyU3luYyhhcHBQYXRoKVxuICAgICAgY29uc3QgaGFzRGVmYXVsdEdyb3VwID0gYXBwSXRlbXMuc29tZShcbiAgICAgICAgKGl0ZW0pID0+IGl0ZW0gPT09ICcoZGVmYXVsdCknIHx8IGl0ZW0uc3RhcnRzV2l0aCgnKCcpXG4gICAgICApXG5cbiAgICAgIGlmICghaGFzRGVmYXVsdEdyb3VwKSB7XG4gICAgICAgIHZpb2xhdGlvbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ2ludmFsaWQtc3JjLWZvbGRlcicsXG4gICAgICAgICAgcGF0aDogJ3NyYy9hcHAnLFxuICAgICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgICAnc3JjL2FwcCBzaG91bGQgaGF2ZSBhdCBsZWFzdCBvbmUgcm91dGUgZ3JvdXAgZm9sZGVyIChlLmcuLCAoZGVmYXVsdCkvKScsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gT3V0cHV0IHJlc3VsdHNcbiAgaWYgKG9wdGlvbnMuanNvbikge1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHtcbiAgICAgICAgICB2YWxpZDogdmlvbGF0aW9ucy5sZW5ndGggPT09IDAsXG4gICAgICAgICAgdmlvbGF0aW9ucyxcbiAgICAgICAgfSxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgMlxuICAgICAgKVxuICAgIClcbiAgfSBlbHNlIHtcbiAgICBpZiAodmlvbGF0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUubG9nKCfinJMgUHJvamVjdCBzdHJ1Y3R1cmUgaXMgdmFsaWQnKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmxvZyhgRm91bmQgJHt2aW9sYXRpb25zLmxlbmd0aH0gdmlvbGF0aW9uKHMpOlxcbmApXG4gICAgICBmb3IgKGNvbnN0IHYgb2YgdmlvbGF0aW9ucykge1xuICAgICAgICBjb25zb2xlLmxvZyhgICDinJcgJHt2Lm1lc3NhZ2V9YClcbiAgICAgIH1cbiAgICAgIGNvbnNvbGUubG9nKCcnKVxuICAgIH1cbiAgfVxuXG4gIC8vIEV4aXQgd2l0aCBlcnJvciBjb2RlIGlmIHN0cmljdCBtb2RlIGFuZCB2aW9sYXRpb25zIGZvdW5kXG4gIGlmIChvcHRpb25zLnN0cmljdCAmJiB2aW9sYXRpb25zLmxlbmd0aCA+IDApIHtcbiAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxufVxuIl19
|
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { audit } from './commands/audit.js';
|
|
3
3
|
import { generate } from './commands/generate.js';
|
|
4
|
+
import { validate } from './commands/validate.js';
|
|
4
5
|
import { version } from '../index.js';
|
|
5
6
|
const args = process.argv.slice(2);
|
|
6
7
|
const command = args[0];
|
|
@@ -27,6 +28,7 @@ ${colors.bold}Usage:${colors.reset}
|
|
|
27
28
|
${colors.bold}Commands:${colors.reset}
|
|
28
29
|
audit [path] Check Canon compliance (default: src/blocks/)
|
|
29
30
|
generate [output] Generate AI rules from Canon (default: .cursorrules)
|
|
31
|
+
validate [path] Validate project folder structure (default: .)
|
|
30
32
|
version Show version information
|
|
31
33
|
help Show this help message
|
|
32
34
|
|
|
@@ -37,12 +39,18 @@ ${colors.bold}Audit Options:${colors.reset}
|
|
|
37
39
|
${colors.bold}Generate Options:${colors.reset}
|
|
38
40
|
--output, -o Output file path (default: .cursorrules)
|
|
39
41
|
|
|
42
|
+
${colors.bold}Validate Options:${colors.reset}
|
|
43
|
+
--strict Exit with error code on violations
|
|
44
|
+
--json Output as JSON
|
|
45
|
+
|
|
40
46
|
${colors.bold}Examples:${colors.reset}
|
|
41
47
|
gallop audit
|
|
42
48
|
gallop audit src/blocks/ --strict
|
|
43
49
|
gallop generate
|
|
44
50
|
gallop generate .cursorrules
|
|
45
51
|
gallop generate --output .github/copilot-instructions.md
|
|
52
|
+
gallop validate
|
|
53
|
+
gallop validate . --strict
|
|
46
54
|
`);
|
|
47
55
|
}
|
|
48
56
|
function showVersion() {
|
|
@@ -80,6 +88,14 @@ async function main() {
|
|
|
80
88
|
};
|
|
81
89
|
await generate(generateOptions);
|
|
82
90
|
break;
|
|
91
|
+
case 'validate':
|
|
92
|
+
const validatePath = args[1] && !args[1].startsWith('--') ? args[1] : '.';
|
|
93
|
+
const validateOptions = {
|
|
94
|
+
strict: args.includes('--strict'),
|
|
95
|
+
json: args.includes('--json'),
|
|
96
|
+
};
|
|
97
|
+
await validate(validatePath, validateOptions);
|
|
98
|
+
break;
|
|
83
99
|
case 'version':
|
|
84
100
|
case '-v':
|
|
85
101
|
case '--version':
|
|
@@ -101,4 +117,4 @@ main().catch((error) => {
|
|
|
101
117
|
console.error('Error:', error.message);
|
|
102
118
|
process.exit(1);
|
|
103
119
|
});
|
|
104
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
120
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2xpL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFFQSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHdCQUF3QixDQUFBO0FBQ2pELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQUNqRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRXJDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ2xDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtBQUV2Qiw2QkFBNkI7QUFDN0IsTUFBTSxNQUFNLEdBQUc7SUFDYixLQUFLLEVBQUUsU0FBUztJQUNoQixJQUFJLEVBQUUsU0FBUztJQUNmLEdBQUcsRUFBRSxTQUFTO0lBQ2QsR0FBRyxFQUFFLFVBQVU7SUFDZixLQUFLLEVBQUUsVUFBVTtJQUNqQixNQUFNLEVBQUUsVUFBVTtJQUNsQixJQUFJLEVBQUUsVUFBVTtJQUNoQixPQUFPLEVBQUUsVUFBVTtJQUNuQixJQUFJLEVBQUUsVUFBVTtDQUNqQixDQUFBO0FBRUQsU0FBUyxRQUFRO0lBQ2YsT0FBTyxDQUFDLEdBQUcsQ0FBQztFQUNaLE1BQU0sQ0FBQyxJQUFJLGFBQWEsTUFBTSxDQUFDLEtBQUs7RUFDcEMsTUFBTSxDQUFDLEdBQUcsa0JBQWtCLE9BQU8sR0FBRyxNQUFNLENBQUMsS0FBSzs7RUFFbEQsTUFBTSxDQUFDLElBQUksU0FBUyxNQUFNLENBQUMsS0FBSzs7O0VBR2hDLE1BQU0sQ0FBQyxJQUFJLFlBQVksTUFBTSxDQUFDLEtBQUs7Ozs7Ozs7RUFPbkMsTUFBTSxDQUFDLElBQUksaUJBQWlCLE1BQU0sQ0FBQyxLQUFLOzs7O0VBSXhDLE1BQU0s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UUFFUCxLQUFLLFNBQVMsQ0FBQztRQUNmLEtBQUssSUFBSSxDQUFDO1FBQ1YsS0FBSyxXQUFXO1lBQ2QsV0FBVyxFQUFFLENBQUE7WUFDYixNQUFLO1FBRVAsS0FBSyxNQUFNLENBQUM7UUFDWixLQUFLLElBQUksQ0FBQztRQUNWLEtBQUssUUFBUSxDQUFDO1FBQ2QsS0FBSyxTQUFTO1lBQ1osUUFBUSxFQUFFLENBQUE7WUFDVixNQUFLO1FBRVA7WUFDRSxPQUFPLENBQUMsS0FBSyxDQUFDLG9CQUFvQixPQUFPLEVBQUUsQ0FBQyxDQUFBO1lBQzVDLE9BQU8sQ0FBQyxLQUFLLENBQUMsMENBQTBDLENBQUMsQ0FBQTtZQUN6RCxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ25CLENBQUM7QUFDSCxDQUFDO0FBRUQsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7SUFDckIsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3RDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDakIsQ0FBQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIjIS91c3IvYmluL2VudiBub2RlXG5cbmltcG9ydCB7IGF1ZGl0IH0gZnJvbSAnLi9jb21tYW5kcy9hdWRpdC5qcydcbmltcG9ydCB7IGdlbmVyYXRlIH0gZnJvbSAnLi9jb21tYW5kcy9nZW5lcmF0ZS5qcydcbmltcG9ydCB7IHZhbGlkYXRlIH0gZnJvbSAnLi9jb21tYW5kcy92YWxpZGF0ZS5qcydcbmltcG9ydCB7IHZlcnNpb24gfSBmcm9tICcuLi9pbmRleC5qcydcblxuY29uc3QgYXJncyA9IHByb2Nlc3MuYXJndi5zbGljZSgyKVxuY29uc3QgY29tbWFuZCA9IGFyZ3NbMF1cblxuLy8gQ29sb3JzIGZvciB0ZXJtaW5hbCBvdXRwdXRcbmNvbnN0IGNvbG9ycyA9IHtcbiAgcmVzZXQ6ICdcXHgxYlswbScsXG4gIGJvbGQ6ICdcXHgxYlsxbScsXG4gIGRpbTogJ1xceDFiWzJtJyxcbiAgcmVkOiAnXFx4MWJbMzFtJyxcbiAgZ3JlZW46ICdcXHgxYlszMm0nLFxuICB5ZWxsb3c6ICdcXHgxYlszM20nLFxuICBibHVlOiAnXFx4MWJbMzRtJyxcbiAgbWFnZW50YTogJ1xceDFiWzM1bScsXG4gIGN5YW46ICdcXHgxYlszNm0nLFxufVxuXG5mdW5jdGlvbiBzaG93SGVscCgpIHtcbiAgY29uc29sZS5sb2coYFxuJHtjb2xvcnMuYm9sZH1HYWxsb3AgQ0xJJHtjb2xvcnMucmVzZXR9IC0gQ2Fub24gQ29tcGxpYW5jZSBUb29saW5nXG4ke2NvbG9ycy5kaW19Q2Fub24gVmVyc2lvbjogJHt2ZXJzaW9ufSR7Y29sb3JzLnJlc2V0fVxuXG4ke2NvbG9ycy5ib2xkfVVzYWdlOiR7Y29sb3JzLnJlc2V0fVxuICBnYWxsb3AgPGNvbW1hbmQ+IFtvcHRpb25zXVxuXG4ke2NvbG9ycy5ib2xkfUNvbW1hbmRzOiR7Y29sb3JzLnJlc2V0fVxuICBhdWRpdCBbcGF0aF0gICAgICAgQ2hlY2sgQ2Fub24gY29tcGxpYW5jZSAoZGVmYXVsdDogc3JjL2Jsb2Nrcy8pXG4gIGdlbmVyYXRlIFtvdXRwdXRdICBHZW5lcmF0ZSBBSSBydWxlcyBmcm9tIENhbm9uIChkZWZhdWx0OiAuY3Vyc29ycnVsZXMpXG4gIHZhbGlkYXRlIFtwYXRoXSAgICBWYWxpZGF0ZSBwcm9qZWN0IGZvbGRlciBzdHJ1Y3R1cmUgKGRlZmF1bHQ6IC4pXG4gIHZlcnNpb24gICAgICAgICAgICBTaG93IHZlcnNpb24gaW5mb3JtYXRpb25cbiAgaGVscCAgICAgICAgICAgICAgIFNob3cgdGhpcyBoZWxwIG1lc3NhZ2VcblxuJHtjb2xvcnMuYm9sZH1BdWRpdCBPcHRpb25zOiR7Y29sb3JzLnJlc2V0fVxuICAtLXN0cmljdCAgICAgICAgICAgRXhpdCB3aXRoIGVycm9yIGNvZGUgb24gdmlvbGF0aW9uc1xuICAtLWpzb24gICAgICAgICAgICAgT3V0cHV0IGFzIEpTT05cblxuJHtjb2xvcnMuYm9sZH1HZW5lcmF0ZSBPcHRpb25zOiR7Y29sb3JzLnJlc2V0fVxuICAtLW91dHB1dCwgLW8gICAgICAgT3V0cHV0IGZpbGUgcGF0aCAoZGVmYXVsdDogLmN1cnNvcnJ1bGVzKVxuXG4ke2NvbG9ycy5ib2xkfVZhbGlkYXRlIE9wdGlvbnM6JHtjb2xvcnMucmVzZXR9XG4gIC0tc3RyaWN0ICAgICAgICAgICBFeGl0IHdpdGggZXJyb3IgY29kZSBvbiB2aW9sYXRpb25zXG4gIC0tanNvbiAgICAgICAgICAgICBPdXRwdXQgYXMgSlNPTlxuXG4ke2NvbG9ycy5ib2xkfUV4YW1wbGVzOiR7Y29sb3JzLnJlc2V0fVxuICBnYWxsb3AgYXVkaXRcbiAgZ2FsbG9wIGF1ZGl0IHNyYy9ibG9ja3MvIC0tc3RyaWN0XG4gIGdhbGxvcCBnZW5lcmF0ZVxuICBnYWxsb3AgZ2VuZXJhdGUgLmN1cnNvcnJ1bGVzXG4gIGdhbGxvcCBnZW5lcmF0ZSAtLW91dHB1dCAuZ2l0aHViL2NvcGlsb3QtaW5zdHJ1Y3Rpb25zLm1kXG4gIGdhbGxvcCB2YWxpZGF0ZVxuICBnYWxsb3AgdmFsaWRhdGUgLiAtLXN0cmljdFxuYClcbn1cblxuZnVuY3Rpb24gc2hvd1ZlcnNpb24oKSB7XG4gIGNvbnNvbGUubG9nKGBHYWxsb3AgQ0xJIHYxLjAuMGApXG4gIGNvbnNvbGUubG9nKGBDYW5vbiB2JHt2ZXJzaW9ufWApXG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7XG4gIHN3aXRjaCAoY29tbWFuZCkge1xuICAgIGNhc2UgJ2F1ZGl0JzpcbiAgICAgIGNvbnN0IGF1ZGl0UGF0aCA9XG4gICAgICAgIGFyZ3NbMV0gJiYgIWFyZ3NbMV0uc3RhcnRzV2l0aCgnLS0nKSA/IGFyZ3NbMV0gOiAnc3JjL2Jsb2Nrcy8nXG4gICAgICBjb25zdCBhdWRpdE9wdGlvbnMgPSB7XG4gICAgICAgIHN0cmljdDogYXJncy5pbmNsdWRlcygnLS1zdHJpY3QnKSxcbiAgICAgICAganNvbjogYXJncy5pbmNsdWRlcygnLS1qc29uJyksXG4gICAgICAgIGZpeDogYXJncy5pbmNsdWRlcygnLS1maXgnKSxcbiAgICAgIH1cbiAgICAgIGF3YWl0IGF1ZGl0KGF1ZGl0UGF0aCwgYXVkaXRPcHRpb25zKVxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ2dlbmVyYXRlJzpcbiAgICAgIC8vIEZpbmQgb3V0cHV0IHBhdGggZnJvbSBhcmdzXG4gICAgICBsZXQgb3V0cHV0UGF0aCA9ICcuY3Vyc29ycnVsZXMnXG4gICAgICBjb25zdCBvdXRwdXRJbmRleCA9IGFyZ3MuaW5kZXhPZignLS1vdXRwdXQnKVxuICAgICAgY29uc3Qgb3V0cHV0SW5kZXhTaG9ydCA9IGFyZ3MuaW5kZXhPZignLW8nKVxuICAgICAgaWYgKG91dHB1dEluZGV4ICE9PSAtMSAmJiBhcmdzW291dHB1dEluZGV4ICsgMV0pIHtcbiAgICAgICAgb3V0cHV0UGF0aCA9IGFyZ3Nbb3V0cHV0SW5kZXggKyAxXVxuICAgICAgfSBlbHNlIGlmIChvdXRwdXRJbmRleFNob3J0ICE9PSAtMSAmJiBhcmdzW291dHB1dEluZGV4U2hvcnQgKyAxXSkge1xuICAgICAgICBvdXRwdXRQYXRoID0gYXJnc1tvdXRwdXRJbmRleFNob3J0ICsgMV1cbiAgICAgIH0gZWxzZSBpZiAoYXJnc1sxXSAmJiAhYXJnc1sxXS5zdGFydHNXaXRoKCctLScpKSB7XG4gICAgICAgIG91dHB1dFBhdGggPSBhcmdzWzFdXG4gICAgICB9XG4gICAgICBjb25zdCBnZW5lcmF0ZU9wdGlvbnMgPSB7XG4gICAgICAgIG91dHB1dDogb3V0cHV0UGF0aCxcbiAgICAgICAgZm9ybWF0OiAnY3Vyc29ycnVsZXMnIGFzIGNvbnN0LFxuICAgICAgfVxuICAgICAgYXdhaXQgZ2VuZXJhdGUoZ2VuZXJhdGVPcHRpb25zKVxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ3ZhbGlkYXRlJzpcbiAgICAgIGNvbnN0IHZhbGlkYXRlUGF0aCA9XG4gICAgICAgIGFyZ3NbMV0gJiYgIWFyZ3NbMV0uc3RhcnRzV2l0aCgnLS0nKSA/IGFyZ3NbMV0gOiAnLidcbiAgICAgIGNvbnN0IHZhbGlkYXRlT3B0aW9ucyA9IHtcbiAgICAgICAgc3RyaWN0OiBhcmdzLmluY2x1ZGVzKCctLXN0cmljdCcpLFxuICAgICAgICBqc29uOiBhcmdzLmluY2x1ZGVzKCctLWpzb24nKSxcbiAgICAgIH1cbiAgICAgIGF3YWl0IHZhbGlkYXRlKHZhbGlkYXRlUGF0aCwgdmFsaWRhdGVPcHRpb25zKVxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ3ZlcnNpb24nOlxuICAgIGNhc2UgJy12JzpcbiAgICBjYXNlICctLXZlcnNpb24nOlxuICAgICAgc2hvd1ZlcnNpb24oKVxuICAgICAgYnJlYWtcblxuICAgIGNhc2UgJ2hlbHAnOlxuICAgIGNhc2UgJy1oJzpcbiAgICBjYXNlICctLWhlbHAnOlxuICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgc2hvd0hlbHAoKVxuICAgICAgYnJlYWtcblxuICAgIGRlZmF1bHQ6XG4gICAgICBjb25zb2xlLmVycm9yKGBVbmtub3duIGNvbW1hbmQ6ICR7Y29tbWFuZH1gKVxuICAgICAgY29uc29sZS5lcnJvcihgUnVuICdnYWxsb3AgaGVscCcgZm9yIHVzYWdlIGluZm9ybWF0aW9uLmApXG4gICAgICBwcm9jZXNzLmV4aXQoMSlcbiAgfVxufVxuXG5tYWluKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gIGNvbnNvbGUuZXJyb3IoJ0Vycm9yOicsIGVycm9yLm1lc3NhZ2UpXG4gIHByb2Nlc3MuZXhpdCgxKVxufSlcbiJdfQ==
|
|
@@ -10,5 +10,8 @@ declare const recommendedRules: {
|
|
|
10
10
|
readonly 'gallop/prefer-layout-components': "warn";
|
|
11
11
|
readonly 'gallop/background-image-rounded': "warn";
|
|
12
12
|
readonly 'gallop/no-inline-styles': "warn";
|
|
13
|
+
readonly 'gallop/no-arbitrary-colors': "warn";
|
|
14
|
+
readonly 'gallop/no-cross-zone-imports': "warn";
|
|
15
|
+
readonly 'gallop/no-data-imports': "warn";
|
|
13
16
|
};
|
|
14
17
|
export default recommendedRules;
|
|
@@ -17,6 +17,12 @@ const recommendedRules = {
|
|
|
17
17
|
'gallop/background-image-rounded': 'warn',
|
|
18
18
|
// No inline styles, use Tailwind exclusively
|
|
19
19
|
'gallop/no-inline-styles': 'warn',
|
|
20
|
+
// Use defined color tokens, not arbitrary colors
|
|
21
|
+
'gallop/no-arbitrary-colors': 'warn',
|
|
22
|
+
// Enforce import boundaries between Canon zones
|
|
23
|
+
'gallop/no-cross-zone-imports': 'warn',
|
|
24
|
+
// Prevent runtime code from importing _data/ directly
|
|
25
|
+
'gallop/no-data-imports': 'warn',
|
|
20
26
|
};
|
|
21
27
|
export default recommendedRules;
|
|
22
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb21tZW5kZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXNsaW50L2NvbmZpZ3MvcmVjb21tZW5kZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRztJQUN2QixxQ0FBcUM7SUFDckMseUJBQXlCLEVBQUUsTUFBTTtJQUVqQyx1Q0FBdUM7SUFDdkMsZ0NBQWdDLEVBQUUsTUFBTTtJQUV4Qyw0REFBNEQ7SUFDNUQsK0JBQStCLEVBQUUsTUFBTTtJQUV2Qyx1REFBdUQ7SUFDdkQscUNBQXFDLEVBQUUsTUFBTTtJQUU3Qyx3REFBd0Q7SUFDeEQsaUNBQWlDLEVBQUUsTUFBTTtJQUV6QyxxREFBcUQ7SUFDckQsaUNBQWlDLEVBQUUsTUFBTTtJQUV6Qyw2Q0FBNkM7SUFDN0MseUJBQXlCLEVBQUUsTUFBTTtJQUVqQyxpREFBaUQ7SUFDakQsNEJBQTRCLEVBQUUsTUFBTTtJQUVwQyxnREFBZ0Q7SUFDaEQsOEJBQThCLEVBQUUsTUFBTTtJQUV0QyxzREFBc0Q7SUFDdEQsd0JBQXdCLEVBQUUsTUFBTTtDQUN4QixDQUFBO0FBRVYsZUFBZSxnQkFBZ0IsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUmVjb21tZW5kZWQgY29uZmlndXJhdGlvbiBmb3IgRVNMaW50IGZsYXQgY29uZmlnXG4gKiBBIHNlbnNpYmxlIGRlZmF1bHQgZm9yIGFueSBHYWxsb3AtYmFzZWQgdGVtcGxhdGVcbiAqL1xuY29uc3QgcmVjb21tZW5kZWRSdWxlcyA9IHtcbiAgLy8gQmxvY2tzIHNob3VsZCBiZSBzZXJ2ZXIgY29tcG9uZW50c1xuICAnZ2FsbG9wL25vLWNsaWVudC1ibG9ja3MnOiAnd2FybicsXG5cbiAgLy8gU2VjdGlvbiBhbHJlYWR5IHByb3ZpZGVzIGNvbnRhaW5tZW50XG4gICdnYWxsb3Avbm8tY29udGFpbmVyLWluLXNlY3Rpb24nOiAnd2FybicsXG5cbiAgLy8gVXNlIGNvbXBvbmVudCBwcm9wcyBpbnN0ZWFkIG9mIGNsYXNzTmFtZSBmb3Igc3R5bGUgdmFsdWVzXG4gICdnYWxsb3AvcHJlZmVyLWNvbXBvbmVudC1wcm9wcyc6ICd3YXJuJyxcblxuICAvLyBVc2UgVHlwb2dyYXBoeSBjb21wb25lbnRzIGluc3RlYWQgb2YgcmF3IHAvc3BhbiB0YWdzXG4gICdnYWxsb3AvcHJlZmVyLXR5cG9ncmFwaHktY29tcG9uZW50cyc6ICd3YXJuJyxcblxuICAvLyBVc2UgR3JpZC9Db2x1bW5zIGluc3RlYWQgb2YgcmF3IGRpdiB3aXRoIGdyaWQgY2xhc3Nlc1xuICAnZ2FsbG9wL3ByZWZlci1sYXlvdXQtY29tcG9uZW50cyc6ICd3YXJuJyxcblxuICAvLyBCYWNrZ3JvdW5kIGltYWdlcyBtdXN0IGhhdmUgcm91bmRlZD1cInJvdW5kZWQtbm9uZVwiXG4gICdnYWxsb3AvYmFja2dyb3VuZC1pbWFnZS1yb3VuZGVkJzogJ3dhcm4nLFxuXG4gIC8vIE5vIGlubGluZSBzdHlsZXMsIHVzZSBUYWlsd2luZCBleGNsdXNpdmVseVxuICAnZ2FsbG9wL25vLWlubGluZS1zdHlsZXMnOiAnd2FybicsXG5cbiAgLy8gVXNlIGRlZmluZWQgY29sb3IgdG9rZW5zLCBub3QgYXJiaXRyYXJ5IGNvbG9yc1xuICAnZ2FsbG9wL25vLWFyYml0cmFyeS1jb2xvcnMnOiAnd2FybicsXG5cbiAgLy8gRW5mb3JjZSBpbXBvcnQgYm91bmRhcmllcyBiZXR3ZWVuIENhbm9uIHpvbmVzXG4gICdnYWxsb3Avbm8tY3Jvc3Mtem9uZS1pbXBvcnRzJzogJ3dhcm4nLFxuXG4gIC8vIFByZXZlbnQgcnVudGltZSBjb2RlIGZyb20gaW1wb3J0aW5nIF9kYXRhLyBkaXJlY3RseVxuICAnZ2FsbG9wL25vLWRhdGEtaW1wb3J0cyc6ICd3YXJuJyxcbn0gYXMgY29uc3RcblxuZXhwb3J0IGRlZmF1bHQgcmVjb21tZW5kZWRSdWxlc1xuIl19
|
package/dist/eslint/index.d.ts
CHANGED
|
@@ -19,6 +19,15 @@ declare const plugin: {
|
|
|
19
19
|
'no-inline-styles': import("@typescript-eslint/utils/ts-eslint").RuleModule<"noInlineStyles", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
20
20
|
name: string;
|
|
21
21
|
};
|
|
22
|
+
'no-arbitrary-colors': import("@typescript-eslint/utils/ts-eslint").RuleModule<"noArbitraryColors", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
23
|
+
name: string;
|
|
24
|
+
};
|
|
25
|
+
'no-cross-zone-imports': import("@typescript-eslint/utils/ts-eslint").RuleModule<"blocksImportBlocks" | "componentsImportBlocks" | "runtimeImportScripts", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
26
|
+
name: string;
|
|
27
|
+
};
|
|
28
|
+
'no-data-imports': import("@typescript-eslint/utils/ts-eslint").RuleModule<"noDataImports", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
29
|
+
name: string;
|
|
30
|
+
};
|
|
22
31
|
};
|
|
23
32
|
/**
|
|
24
33
|
* Recommended rule configurations - spread into your ESLint config
|
|
@@ -32,6 +41,9 @@ declare const plugin: {
|
|
|
32
41
|
readonly 'gallop/prefer-layout-components': "warn";
|
|
33
42
|
readonly 'gallop/background-image-rounded': "warn";
|
|
34
43
|
readonly 'gallop/no-inline-styles': "warn";
|
|
44
|
+
readonly 'gallop/no-arbitrary-colors': "warn";
|
|
45
|
+
readonly 'gallop/no-cross-zone-imports': "warn";
|
|
46
|
+
readonly 'gallop/no-data-imports': "warn";
|
|
35
47
|
};
|
|
36
48
|
};
|
|
37
49
|
export default plugin;
|
package/dist/eslint/index.js
CHANGED
|
@@ -5,6 +5,9 @@ import preferTypographyComponents from './rules/prefer-typography-components.js'
|
|
|
5
5
|
import preferLayoutComponents from './rules/prefer-layout-components.js';
|
|
6
6
|
import backgroundImageRounded from './rules/background-image-rounded.js';
|
|
7
7
|
import noInlineStyles from './rules/no-inline-styles.js';
|
|
8
|
+
import noArbitraryColors from './rules/no-arbitrary-colors.js';
|
|
9
|
+
import noCrossZoneImports from './rules/no-cross-zone-imports.js';
|
|
10
|
+
import noDataImports from './rules/no-data-imports.js';
|
|
8
11
|
/**
|
|
9
12
|
* All Canon ESLint rules with recommended severity levels
|
|
10
13
|
*/
|
|
@@ -16,11 +19,14 @@ const recommended = {
|
|
|
16
19
|
'gallop/prefer-layout-components': 'warn',
|
|
17
20
|
'gallop/background-image-rounded': 'warn',
|
|
18
21
|
'gallop/no-inline-styles': 'warn',
|
|
22
|
+
'gallop/no-arbitrary-colors': 'warn',
|
|
23
|
+
'gallop/no-cross-zone-imports': 'warn',
|
|
24
|
+
'gallop/no-data-imports': 'warn',
|
|
19
25
|
};
|
|
20
26
|
const plugin = {
|
|
21
27
|
meta: {
|
|
22
28
|
name: 'eslint-plugin-gallop',
|
|
23
|
-
version: '2.
|
|
29
|
+
version: '2.7.0',
|
|
24
30
|
},
|
|
25
31
|
rules: {
|
|
26
32
|
'no-client-blocks': noClientBlocks,
|
|
@@ -30,6 +36,9 @@ const plugin = {
|
|
|
30
36
|
'prefer-layout-components': preferLayoutComponents,
|
|
31
37
|
'background-image-rounded': backgroundImageRounded,
|
|
32
38
|
'no-inline-styles': noInlineStyles,
|
|
39
|
+
'no-arbitrary-colors': noArbitraryColors,
|
|
40
|
+
'no-cross-zone-imports': noCrossZoneImports,
|
|
41
|
+
'no-data-imports': noDataImports,
|
|
33
42
|
},
|
|
34
43
|
/**
|
|
35
44
|
* Recommended rule configurations - spread into your ESLint config
|
|
@@ -38,4 +47,4 @@ const plugin = {
|
|
|
38
47
|
recommended,
|
|
39
48
|
};
|
|
40
49
|
export default plugin;
|
|
41
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZXNsaW50L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sY0FBYyxNQUFNLDZCQUE2QixDQUFBO0FBQ3hELE9BQU8sb0JBQW9CLE1BQU0sb0NBQW9DLENBQUE7QUFDckUsT0FBTyxvQkFBb0IsTUFBTSxtQ0FBbUMsQ0FBQTtBQUNwRSxPQUFPLDBCQUEwQixNQUFNLHlDQUF5QyxDQUFBO0FBQ2hGLE9BQU8sc0JBQXNCLE1BQU0scUNBQXFDLENBQUE7QUFDeEUsT0FBTyxzQkFBc0IsTUFBTSxxQ0FBcUMsQ0FBQTtBQUN4RSxPQUFPLGNBQWMsTUFBTSw2QkFBNkIsQ0FBQTtBQUN4RCxPQUFPLGlCQUFpQixNQUFNLGdDQUFnQyxDQUFBO0FBQzlELE9BQU8sa0JBQWtCLE1BQU0sa0NBQWtDLENBQUE7QUFDakUsT0FBTyxhQUFhLE1BQU0sNEJBQTRCLENBQUE7QUFFdEQ7O0dBRUc7QUFDSCxNQUFNLFdBQVcsR0FBRztJQUNsQix5QkFBeUIsRUFBRSxNQUFNO0lBQ2pDLGdDQUFnQyxFQUFFLE1BQU07SUFDeEMsK0JBQStCLEVBQUUsTUFBTTtJQUN2QyxxQ0FBcUMsRUFBRSxNQUFNO0lBQzdDLGlDQUFpQyxFQUFFLE1BQU07SUFDekMsaUNBQWlDLEVBQUUsTUFBTTtJQUN6Qyx5QkFBeUIsRUFBRSxNQUFNO0lBQ2pDLDRCQUE0QixFQUFFLE1BQU07SUFDcEMsOEJBQThCLEVBQUUsTUFBTTtJQUN0Qyx3QkFBd0IsRUFBRSxNQUFNO0NBQ3hCLENBQUE7QUFFVixNQUFNLE1BQU0sR0FBRztJQUNiLElBQUksRUFBRTtRQUNKLElBQUksRUFBRSxzQkFBc0I7UUFDNUIsT0FBTyxFQUFFLE9BQU87S0FDakI7SUFDRCxLQUFLLEVBQUU7UUFDTCxrQkFBa0IsRUFBRSxjQUFjO1FBQ2xDLHlCQUF5QixFQUFFLG9CQUFvQjtRQUMvQyx3QkFBd0IsRUFBRSxvQkFBb0I7UUFDOUMsOEJBQThCLEVBQUUsMEJBQTBCO1FBQzFELDBCQUEwQixFQUFFLHNCQUFzQjtRQUNsRCwwQkFBMEIsRUFBRSxzQkFBc0I7UUFDbEQsa0JBQWtCLEVBQUUsY0FBYztRQUNsQyxxQkFBcUIsRUFBRSxpQkFBaUI7UUFDeEMsdUJBQXVCLEVBQUUsa0JBQWtCO1FBQzNDLGlCQUFpQixFQUFFLGFBQWE7S0FDakM7SUFDRDs7O09BR0c7SUFDSCxXQUFXO0NBQ1osQ0FBQTtBQUVELGVBQWUsTUFBTSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG5vQ2xpZW50QmxvY2tzIGZyb20gJy4vcnVsZXMvbm8tY2xpZW50LWJsb2Nrcy5qcydcbmltcG9ydCBub0NvbnRhaW5lckluU2VjdGlvbiBmcm9tICcuL3J1bGVzL25vLWNvbnRhaW5lci1pbi1zZWN0aW9uLmpzJ1xuaW1wb3J0IHByZWZlckNvbXBvbmVudFByb3BzIGZyb20gJy4vcnVsZXMvcHJlZmVyLWNvbXBvbmVudC1wcm9wcy5qcydcbmltcG9ydCBwcmVmZXJUeXBvZ3JhcGh5Q29tcG9uZW50cyBmcm9tICcuL3J1bGVzL3ByZWZlci10eXBvZ3JhcGh5LWNvbXBvbmVudHMuanMnXG5pbXBvcnQgcHJlZmVyTGF5b3V0Q29tcG9uZW50cyBmcm9tICcuL3J1bGVzL3ByZWZlci1sYXlvdXQtY29tcG9uZW50cy5qcydcbmltcG9ydCBiYWNrZ3JvdW5kSW1hZ2VSb3VuZGVkIGZyb20gJy4vcnVsZXMvYmFja2dyb3VuZC1pbWFnZS1yb3VuZGVkLmpzJ1xuaW1wb3J0IG5vSW5saW5lU3R5bGVzIGZyb20gJy4vcnVsZXMvbm8taW5saW5lLXN0eWxlcy5qcydcbmltcG9ydCBub0FyYml0cmFyeUNvbG9ycyBmcm9tICcuL3J1bGVzL25vLWFyYml0cmFyeS1jb2xvcnMuanMnXG5pbXBvcnQgbm9Dcm9zc1pvbmVJbXBvcnRzIGZyb20gJy4vcnVsZXMvbm8tY3Jvc3Mtem9uZS1pbXBvcnRzLmpzJ1xuaW1wb3J0IG5vRGF0YUltcG9ydHMgZnJvbSAnLi9ydWxlcy9uby1kYXRhLWltcG9ydHMuanMnXG5cbi8qKlxuICogQWxsIENhbm9uIEVTTGludCBydWxlcyB3aXRoIHJlY29tbWVuZGVkIHNldmVyaXR5IGxldmVsc1xuICovXG5jb25zdCByZWNvbW1lbmRlZCA9IHtcbiAgJ2dhbGxvcC9uby1jbGllbnQtYmxvY2tzJzogJ3dhcm4nLFxuICAnZ2FsbG9wL25vLWNvbnRhaW5lci1pbi1zZWN0aW9uJzogJ3dhcm4nLFxuICAnZ2FsbG9wL3ByZWZlci1jb21wb25lbnQtcHJvcHMnOiAnd2FybicsXG4gICdnYWxsb3AvcHJlZmVyLXR5cG9ncmFwaHktY29tcG9uZW50cyc6ICd3YXJuJyxcbiAgJ2dhbGxvcC9wcmVmZXItbGF5b3V0LWNvbXBvbmVudHMnOiAnd2FybicsXG4gICdnYWxsb3AvYmFja2dyb3VuZC1pbWFnZS1yb3VuZGVkJzogJ3dhcm4nLFxuICAnZ2FsbG9wL25vLWlubGluZS1zdHlsZXMnOiAnd2FybicsXG4gICdnYWxsb3Avbm8tYXJiaXRyYXJ5LWNvbG9ycyc6ICd3YXJuJyxcbiAgJ2dhbGxvcC9uby1jcm9zcy16b25lLWltcG9ydHMnOiAnd2FybicsXG4gICdnYWxsb3Avbm8tZGF0YS1pbXBvcnRzJzogJ3dhcm4nLFxufSBhcyBjb25zdFxuXG5jb25zdCBwbHVnaW4gPSB7XG4gIG1ldGE6IHtcbiAgICBuYW1lOiAnZXNsaW50LXBsdWdpbi1nYWxsb3AnLFxuICAgIHZlcnNpb246ICcyLjcuMCcsXG4gIH0sXG4gIHJ1bGVzOiB7XG4gICAgJ25vLWNsaWVudC1ibG9ja3MnOiBub0NsaWVudEJsb2NrcyxcbiAgICAnbm8tY29udGFpbmVyLWluLXNlY3Rpb24nOiBub0NvbnRhaW5lckluU2VjdGlvbixcbiAgICAncHJlZmVyLWNvbXBvbmVudC1wcm9wcyc6IHByZWZlckNvbXBvbmVudFByb3BzLFxuICAgICdwcmVmZXItdHlwb2dyYXBoeS1jb21wb25lbnRzJzogcHJlZmVyVHlwb2dyYXBoeUNvbXBvbmVudHMsXG4gICAgJ3ByZWZlci1sYXlvdXQtY29tcG9uZW50cyc6IHByZWZlckxheW91dENvbXBvbmVudHMsXG4gICAgJ2JhY2tncm91bmQtaW1hZ2Utcm91bmRlZCc6IGJhY2tncm91bmRJbWFnZVJvdW5kZWQsXG4gICAgJ25vLWlubGluZS1zdHlsZXMnOiBub0lubGluZVN0eWxlcyxcbiAgICAnbm8tYXJiaXRyYXJ5LWNvbG9ycyc6IG5vQXJiaXRyYXJ5Q29sb3JzLFxuICAgICduby1jcm9zcy16b25lLWltcG9ydHMnOiBub0Nyb3NzWm9uZUltcG9ydHMsXG4gICAgJ25vLWRhdGEtaW1wb3J0cyc6IG5vRGF0YUltcG9ydHMsXG4gIH0sXG4gIC8qKlxuICAgKiBSZWNvbW1lbmRlZCBydWxlIGNvbmZpZ3VyYXRpb25zIC0gc3ByZWFkIGludG8geW91ciBFU0xpbnQgY29uZmlnXG4gICAqIEBleGFtcGxlIHJ1bGVzOiB7IC4uLmdhbGxvcC5yZWNvbW1lbmRlZCB9XG4gICAqL1xuICByZWNvbW1lbmRlZCxcbn1cblxuZXhwb3J0IGRlZmF1bHQgcGx1Z2luXG4iXX0=
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
import { getCanonUrl, getCanonPattern } from '../utils/canon.js';
|
|
3
|
+
const RULE_NAME = 'no-arbitrary-colors';
|
|
4
|
+
const pattern = getCanonPattern(RULE_NAME);
|
|
5
|
+
const createRule = ESLintUtils.RuleCreator(() => getCanonUrl(RULE_NAME));
|
|
6
|
+
// Patterns that indicate arbitrary color values in Tailwind classes
|
|
7
|
+
const COLOR_PREFIXES = [
|
|
8
|
+
'bg',
|
|
9
|
+
'text',
|
|
10
|
+
'border',
|
|
11
|
+
'ring',
|
|
12
|
+
'outline',
|
|
13
|
+
'shadow',
|
|
14
|
+
'accent',
|
|
15
|
+
'caret',
|
|
16
|
+
'fill',
|
|
17
|
+
'stroke',
|
|
18
|
+
'decoration',
|
|
19
|
+
'divide',
|
|
20
|
+
'from',
|
|
21
|
+
'via',
|
|
22
|
+
'to',
|
|
23
|
+
];
|
|
24
|
+
// Regex to match arbitrary color values like bg-[#fff], text-[rgb(...)], border-[hsl(...)]
|
|
25
|
+
const ARBITRARY_COLOR_REGEX = new RegExp(`\\b(${COLOR_PREFIXES.join('|')})-\\[(?:#[0-9a-fA-F]{3,8}|rgb[a]?\\(|hsl[a]?\\(|color\\(|oklch\\(|oklab\\()`, 'i');
|
|
26
|
+
// Also match var() references to non-color custom properties in color contexts
|
|
27
|
+
const ARBITRARY_VAR_COLOR_REGEX = new RegExp(`\\b(${COLOR_PREFIXES.join('|')})-\\[var\\(--(?!color-)`, 'i');
|
|
28
|
+
export default createRule({
|
|
29
|
+
name: RULE_NAME,
|
|
30
|
+
meta: {
|
|
31
|
+
type: 'suggestion',
|
|
32
|
+
docs: {
|
|
33
|
+
description: pattern?.summary || 'Use defined color tokens, not arbitrary color values',
|
|
34
|
+
},
|
|
35
|
+
messages: {
|
|
36
|
+
noArbitraryColors: `[Canon ${pattern?.id || '020'}] Avoid arbitrary color values. Use defined Tailwind color tokens (e.g., bg-accent, text-contrast) instead of hardcoded colors. See: ${pattern?.title || 'No Arbitrary Colors'} pattern.`,
|
|
37
|
+
},
|
|
38
|
+
schema: [],
|
|
39
|
+
},
|
|
40
|
+
defaultOptions: [],
|
|
41
|
+
create(context) {
|
|
42
|
+
return {
|
|
43
|
+
JSXAttribute(node) {
|
|
44
|
+
// Only check className attributes
|
|
45
|
+
if (node.name.type !== 'JSXIdentifier' ||
|
|
46
|
+
node.name.name !== 'className') {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Get the className value
|
|
50
|
+
let classValue = '';
|
|
51
|
+
if (node.value?.type === 'Literal' && typeof node.value.value === 'string') {
|
|
52
|
+
classValue = node.value.value;
|
|
53
|
+
}
|
|
54
|
+
else if (node.value?.type === 'JSXExpressionContainer' &&
|
|
55
|
+
node.value.expression.type === 'Literal' &&
|
|
56
|
+
typeof node.value.expression.value === 'string') {
|
|
57
|
+
classValue = node.value.expression.value;
|
|
58
|
+
}
|
|
59
|
+
else if (node.value?.type === 'JSXExpressionContainer' &&
|
|
60
|
+
node.value.expression.type === 'TemplateLiteral') {
|
|
61
|
+
// Extract string parts from template literal
|
|
62
|
+
classValue = node.value.expression.quasis
|
|
63
|
+
.map((quasi) => quasi.value.raw)
|
|
64
|
+
.join(' ');
|
|
65
|
+
}
|
|
66
|
+
if (!classValue)
|
|
67
|
+
return;
|
|
68
|
+
// Check for arbitrary color values
|
|
69
|
+
if (ARBITRARY_COLOR_REGEX.test(classValue) ||
|
|
70
|
+
ARBITRARY_VAR_COLOR_REGEX.test(classValue)) {
|
|
71
|
+
context.report({
|
|
72
|
+
node,
|
|
73
|
+
messageId: 'noArbitraryColors',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tYXJiaXRyYXJ5LWNvbG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9lc2xpbnQvcnVsZXMvbm8tYXJiaXRyYXJ5LWNvbG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMEJBQTBCLENBQUE7QUFDdEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUVoRSxNQUFNLFNBQVMsR0FBRyxxQkFBcUIsQ0FBQTtBQUN2QyxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUE7QUFFMUMsTUFBTSxVQUFVLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQTtBQUl4RSxvRUFBb0U7QUFDcEUsTUFBTSxjQUFjLEdBQUc7SUFDckIsSUFBSTtJQUNKLE1BQU07SUFDTixRQUFRO0lBQ1IsTUFBTTtJQUNOLFNBQVM7SUFDVCxRQUFRO0lBQ1IsUUFBUTtJQUNSLE9BQU87SUFDUCxNQUFNO0lBQ04sUUFBUTtJQUNSLFlBQVk7SUFDWixRQUFRO0lBQ1IsTUFBTTtJQUNOLEtBQUs7SUFDTCxJQUFJO0NBQ0wsQ0FBQTtBQUVELDJGQUEyRjtBQUMzRixNQUFNLHFCQUFxQixHQUFHLElBQUksTUFBTSxDQUN0QyxPQUFPLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDZFQUE2RSxFQUM1RyxHQUFHLENBQ0osQ0FBQTtBQUVELCtFQUErRTtBQUMvRSxNQUFNLHlCQUF5QixHQUFHLElBQUksTUFBTSxDQUMxQyxPQUFPLGNBQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHlCQUF5QixFQUN4RCxHQUFHLENBQ0osQ0FBQTtBQUVELGVBQWUsVUFBVSxDQUFpQjtJQUN4QyxJQUFJLEVBQUUsU0FBUztJQUNmLElBQUksRUFBRTtRQUNKLElBQUksRUFBRSxZQUFZO1FBQ2xCLElBQUksRUFBRTtZQUNKLFdBQVcsRUFDVCxPQUFPLEVBQUUsT0FBTyxJQUFJLHNEQUFzRDtTQUM3RTtRQUNELFFBQVEsRUFBRTtZQUNSLGlCQUFpQixFQUFFLFVBQVUsT0FBTyxFQUFFLEVBQUUsSUFBSSxLQUFLLHdJQUF3SSxPQUFPLEVBQUUsS0FBSyxJQUFJLHFCQUFxQixXQUFXO1NBQzVPO1FBQ0QsTUFBTSxFQUFFLEVBQUU7S0FDWDtJQUNELGNBQWMsRUFBRSxFQUFFO0lBQ2xCLE1BQU0sQ0FBQyxPQUFPO1FBQ1osT0FBTztZQUNMLFlBQVksQ0FBQyxJQUFJO2dCQUNmLGtDQUFrQztnQkFDbEMsSUFDRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxlQUFlO29CQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxXQUFXLEVBQzlCLENBQUM7b0JBQ0QsT0FBTTtnQkFDUixDQUFDO2dCQUVELDBCQUEwQjtnQkFDMUIsSUFBSSxVQUFVLEdBQUcsRUFBRSxDQUFBO2dCQUVuQixJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxLQUFLLFNBQVMsSUFBSSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO29CQUMzRSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUE7Z0JBQy9CLENBQUM7cUJBQU0sSUFDTCxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksS0FBSyx3QkFBd0I7b0JBQzdDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxTQUFTO29CQUN4QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssS0FBSyxRQUFRLEVBQy9DLENBQUM7b0JBQ0QsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQTtnQkFDMUMsQ0FBQztxQkFBTSxJQUNMLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxLQUFLLHdCQUF3QjtvQkFDN0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLGlCQUFpQixFQUNoRCxDQUFDO29CQUNELDZDQUE2QztvQkFDN0MsVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU07eUJBQ3RDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7eUJBQy9CLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtnQkFDZCxDQUFDO2dCQUVELElBQUksQ0FBQyxVQUFVO29CQUFFLE9BQU07Z0JBRXZCLG1DQUFtQztnQkFDbkMsSUFDRSxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO29CQUN0Qyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQzFDLENBQUM7b0JBQ0QsT0FBTyxDQUFDLE1BQU0sQ0FBQzt3QkFDYixJQUFJO3dCQUNKLFNBQVMsRUFBRSxtQkFBbUI7cUJBQy9CLENBQUMsQ0FBQTtnQkFDSixDQUFDO1lBQ0gsQ0FBQztTQUNGLENBQUE7SUFDSCxDQUFDO0NBQ0YsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRVNMaW50VXRpbHMgfSBmcm9tICdAdHlwZXNjcmlwdC1lc2xpbnQvdXRpbHMnXG5pbXBvcnQgeyBnZXRDYW5vblVybCwgZ2V0Q2Fub25QYXR0ZXJuIH0gZnJvbSAnLi4vdXRpbHMvY2Fub24uanMnXG5cbmNvbnN0IFJVTEVfTkFNRSA9ICduby1hcmJpdHJhcnktY29sb3JzJ1xuY29uc3QgcGF0dGVybiA9IGdldENhbm9uUGF0dGVybihSVUxFX05BTUUpXG5cbmNvbnN0IGNyZWF0ZVJ1bGUgPSBFU0xpbnRVdGlscy5SdWxlQ3JlYXRvcigoKSA9PiBnZXRDYW5vblVybChSVUxFX05BTUUpKVxuXG50eXBlIE1lc3NhZ2VJZHMgPSAnbm9BcmJpdHJhcnlDb2xvcnMnXG5cbi8vIFBhdHRlcm5zIHRoYXQgaW5kaWNhdGUgYXJiaXRyYXJ5IGNvbG9yIHZhbHVlcyBpbiBUYWlsd2luZCBjbGFzc2VzXG5jb25zdCBDT0xPUl9QUkVGSVhFUyA9IFtcbiAgJ2JnJyxcbiAgJ3RleHQnLFxuICAnYm9yZGVyJyxcbiAgJ3JpbmcnLFxuICAnb3V0bGluZScsXG4gICdzaGFkb3cnLFxuICAnYWNjZW50JyxcbiAgJ2NhcmV0JyxcbiAgJ2ZpbGwnLFxuICAnc3Ryb2tlJyxcbiAgJ2RlY29yYXRpb24nLFxuICAnZGl2aWRlJyxcbiAgJ2Zyb20nLFxuICAndmlhJyxcbiAgJ3RvJyxcbl1cblxuLy8gUmVnZXggdG8gbWF0Y2ggYXJiaXRyYXJ5IGNvbG9yIHZhbHVlcyBsaWtlIGJnLVsjZmZmXSwgdGV4dC1bcmdiKC4uLildLCBib3JkZXItW2hzbCguLi4pXVxuY29uc3QgQVJCSVRSQVJZX0NPTE9SX1JFR0VYID0gbmV3IFJlZ0V4cChcbiAgYFxcXFxiKCR7Q09MT1JfUFJFRklYRVMuam9pbignfCcpfSktXFxcXFsoPzojWzAtOWEtZkEtRl17Myw4fXxyZ2JbYV0/XFxcXCh8aHNsW2FdP1xcXFwofGNvbG9yXFxcXCh8b2tsY2hcXFxcKHxva2xhYlxcXFwoKWAsXG4gICdpJ1xuKVxuXG4vLyBBbHNvIG1hdGNoIHZhcigpIHJlZmVyZW5jZXMgdG8gbm9uLWNvbG9yIGN1c3RvbSBwcm9wZXJ0aWVzIGluIGNvbG9yIGNvbnRleHRzXG5jb25zdCBBUkJJVFJBUllfVkFSX0NPTE9SX1JFR0VYID0gbmV3IFJlZ0V4cChcbiAgYFxcXFxiKCR7Q09MT1JfUFJFRklYRVMuam9pbignfCcpfSktXFxcXFt2YXJcXFxcKC0tKD8hY29sb3ItKWAsXG4gICdpJ1xuKVxuXG5leHBvcnQgZGVmYXVsdCBjcmVhdGVSdWxlPFtdLCBNZXNzYWdlSWRzPih7XG4gIG5hbWU6IFJVTEVfTkFNRSxcbiAgbWV0YToge1xuICAgIHR5cGU6ICdzdWdnZXN0aW9uJyxcbiAgICBkb2NzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgcGF0dGVybj8uc3VtbWFyeSB8fCAnVXNlIGRlZmluZWQgY29sb3IgdG9rZW5zLCBub3QgYXJiaXRyYXJ5IGNvbG9yIHZhbHVlcycsXG4gICAgfSxcbiAgICBtZXNzYWdlczoge1xuICAgICAgbm9BcmJpdHJhcnlDb2xvcnM6IGBbQ2Fub24gJHtwYXR0ZXJuPy5pZCB8fCAnMDIwJ31dIEF2b2lkIGFyYml0cmFyeSBjb2xvciB2YWx1ZXMuIFVzZSBkZWZpbmVkIFRhaWx3aW5kIGNvbG9yIHRva2VucyAoZS5nLiwgYmctYWNjZW50LCB0ZXh0LWNvbnRyYXN0KSBpbnN0ZWFkIG9mIGhhcmRjb2RlZCBjb2xvcnMuIFNlZTogJHtwYXR0ZXJuPy50aXRsZSB8fCAnTm8gQXJiaXRyYXJ5IENvbG9ycyd9IHBhdHRlcm4uYCxcbiAgICB9LFxuICAgIHNjaGVtYTogW10sXG4gIH0sXG4gIGRlZmF1bHRPcHRpb25zOiBbXSxcbiAgY3JlYXRlKGNvbnRleHQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgSlNYQXR0cmlidXRlKG5vZGUpIHtcbiAgICAgICAgLy8gT25seSBjaGVjayBjbGFzc05hbWUgYXR0cmlidXRlc1xuICAgICAgICBpZiAoXG4gICAgICAgICAgbm9kZS5uYW1lLnR5cGUgIT09ICdKU1hJZGVudGlmaWVyJyB8fFxuICAgICAgICAgIG5vZGUubmFtZS5uYW1lICE9PSAnY2xhc3NOYW1lJ1xuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgY2xhc3NOYW1lIHZhbHVlXG4gICAgICAgIGxldCBjbGFzc1ZhbHVlID0gJydcblxuICAgICAgICBpZiAobm9kZS52YWx1ZT8udHlwZSA9PT0gJ0xpdGVyYWwnICYmIHR5cGVvZiBub2RlLnZhbHVlLnZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGNsYXNzVmFsdWUgPSBub2RlLnZhbHVlLnZhbHVlXG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgbm9kZS52YWx1ZT8udHlwZSA9PT0gJ0pTWEV4cHJlc3Npb25Db250YWluZXInICYmXG4gICAgICAgICAgbm9kZS52YWx1ZS5leHByZXNzaW9uLnR5cGUgPT09ICdMaXRlcmFsJyAmJlxuICAgICAgICAgIHR5cGVvZiBub2RlLnZhbHVlLmV4cHJlc3Npb24udmFsdWUgPT09ICdzdHJpbmcnXG4gICAgICAgICkge1xuICAgICAgICAgIGNsYXNzVmFsdWUgPSBub2RlLnZhbHVlLmV4cHJlc3Npb24udmFsdWVcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBub2RlLnZhbHVlPy50eXBlID09PSAnSlNYRXhwcmVzc2lvbkNvbnRhaW5lcicgJiZcbiAgICAgICAgICBub2RlLnZhbHVlLmV4cHJlc3Npb24udHlwZSA9PT0gJ1RlbXBsYXRlTGl0ZXJhbCdcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gRXh0cmFjdCBzdHJpbmcgcGFydHMgZnJvbSB0ZW1wbGF0ZSBsaXRlcmFsXG4gICAgICAgICAgY2xhc3NWYWx1ZSA9IG5vZGUudmFsdWUuZXhwcmVzc2lvbi5xdWFzaXNcbiAgICAgICAgICAgIC5tYXAoKHF1YXNpKSA9PiBxdWFzaS52YWx1ZS5yYXcpXG4gICAgICAgICAgICAuam9pbignICcpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWNsYXNzVmFsdWUpIHJldHVyblxuXG4gICAgICAgIC8vIENoZWNrIGZvciBhcmJpdHJhcnkgY29sb3IgdmFsdWVzXG4gICAgICAgIGlmIChcbiAgICAgICAgICBBUkJJVFJBUllfQ09MT1JfUkVHRVgudGVzdChjbGFzc1ZhbHVlKSB8fFxuICAgICAgICAgIEFSQklUUkFSWV9WQVJfQ09MT1JfUkVHRVgudGVzdChjbGFzc1ZhbHVlKVxuICAgICAgICApIHtcbiAgICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgbWVzc2FnZUlkOiAnbm9BcmJpdHJhcnlDb2xvcnMnLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfVxuICB9LFxufSlcbiJdfQ==
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
type MessageIds = 'blocksImportBlocks' | 'componentsImportBlocks' | 'runtimeImportScripts';
|
|
3
|
+
declare const _default: ESLintUtils.RuleModule<MessageIds, [], unknown, ESLintUtils.RuleListener> & {
|
|
4
|
+
name: string;
|
|
5
|
+
};
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
import { getCanonUrl, getCanonPattern } from '../utils/canon.js';
|
|
3
|
+
const RULE_NAME = 'no-cross-zone-imports';
|
|
4
|
+
const pattern = getCanonPattern(RULE_NAME);
|
|
5
|
+
const createRule = ESLintUtils.RuleCreator(() => getCanonUrl(RULE_NAME));
|
|
6
|
+
/**
|
|
7
|
+
* Determine which zone a file is in based on its path
|
|
8
|
+
*/
|
|
9
|
+
function getZone(filename) {
|
|
10
|
+
if (filename.includes('/blocks/') || filename.includes('\\blocks\\')) {
|
|
11
|
+
return 'blocks';
|
|
12
|
+
}
|
|
13
|
+
if (filename.includes('/components/') || filename.includes('\\components\\')) {
|
|
14
|
+
return 'components';
|
|
15
|
+
}
|
|
16
|
+
if (filename.includes('/app/') || filename.includes('\\app\\')) {
|
|
17
|
+
return 'app';
|
|
18
|
+
}
|
|
19
|
+
if (filename.includes('/hooks/') || filename.includes('\\hooks\\')) {
|
|
20
|
+
return 'hooks';
|
|
21
|
+
}
|
|
22
|
+
if (filename.includes('/utils/') || filename.includes('\\utils\\')) {
|
|
23
|
+
return 'utils';
|
|
24
|
+
}
|
|
25
|
+
if (filename.includes('/tools/') || filename.includes('\\tools\\')) {
|
|
26
|
+
return 'tools';
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if an import path targets a specific zone
|
|
32
|
+
*/
|
|
33
|
+
function importsZone(importPath, zone) {
|
|
34
|
+
// Handle alias imports like @/blocks/... or @/components/...
|
|
35
|
+
if (importPath.startsWith('@/')) {
|
|
36
|
+
return importPath.startsWith(`@/${zone}/`);
|
|
37
|
+
}
|
|
38
|
+
// Handle relative imports
|
|
39
|
+
return importPath.includes(`/${zone}/`) || importPath.includes(`\\${zone}\\`);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if an import targets _scripts
|
|
43
|
+
*/
|
|
44
|
+
function importsScripts(importPath) {
|
|
45
|
+
return (importPath.includes('_scripts/') ||
|
|
46
|
+
importPath.includes('_scripts\\') ||
|
|
47
|
+
importPath.startsWith('@/_scripts/'));
|
|
48
|
+
}
|
|
49
|
+
export default createRule({
|
|
50
|
+
name: RULE_NAME,
|
|
51
|
+
meta: {
|
|
52
|
+
type: 'problem',
|
|
53
|
+
docs: {
|
|
54
|
+
description: pattern?.summary || 'Enforce import boundaries between Canon zones',
|
|
55
|
+
},
|
|
56
|
+
messages: {
|
|
57
|
+
blocksImportBlocks: `[Canon ${pattern?.id || '021'}] Blocks cannot import from other blocks. Each block should be self-contained or import from components.`,
|
|
58
|
+
componentsImportBlocks: `[Canon ${pattern?.id || '021'}] Components cannot import from blocks. Blocks compose components, not the other way around.`,
|
|
59
|
+
runtimeImportScripts: `[Canon ${pattern?.id || '021'}] Runtime code cannot import from _scripts/. Scripts are for build-time only.`,
|
|
60
|
+
},
|
|
61
|
+
schema: [],
|
|
62
|
+
},
|
|
63
|
+
defaultOptions: [],
|
|
64
|
+
create(context) {
|
|
65
|
+
const filename = context.filename || context.getFilename();
|
|
66
|
+
const currentZone = getZone(filename);
|
|
67
|
+
// Skip files not in a known zone
|
|
68
|
+
if (!currentZone) {
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
ImportDeclaration(node) {
|
|
73
|
+
const importPath = node.source.value;
|
|
74
|
+
// Rule 1: Blocks cannot import from other blocks
|
|
75
|
+
if (currentZone === 'blocks' && importsZone(importPath, 'blocks')) {
|
|
76
|
+
context.report({
|
|
77
|
+
node,
|
|
78
|
+
messageId: 'blocksImportBlocks',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// Rule 2: Components cannot import from blocks
|
|
82
|
+
if (currentZone === 'components' && importsZone(importPath, 'blocks')) {
|
|
83
|
+
context.report({
|
|
84
|
+
node,
|
|
85
|
+
messageId: 'componentsImportBlocks',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// Rule 3: No runtime code can import from _scripts
|
|
89
|
+
if (importsScripts(importPath)) {
|
|
90
|
+
context.report({
|
|
91
|
+
node,
|
|
92
|
+
messageId: 'runtimeImportScripts',
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tY3Jvc3Mtem9uZS1pbXBvcnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VzbGludC9ydWxlcy9uby1jcm9zcy16b25lLWltcG9ydHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFBO0FBQ3RELE9BQU8sRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFFaEUsTUFBTSxTQUFTLEdBQUcsdUJBQXVCLENBQUE7QUFDekMsTUFBTSxPQUFPLEdBQUcsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0FBRTFDLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUE7QUFJeEU7O0dBRUc7QUFDSCxTQUFTLE9BQU8sQ0FBQyxRQUFnQjtJQUMvQixJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQ3JFLE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7SUFDRCxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7UUFDN0UsT0FBTyxZQUFZLENBQUE7SUFDckIsQ0FBQztJQUNELElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDL0QsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBQ0QsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztRQUNuRSxPQUFPLE9B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LENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztvQkFDL0IsT0FBTyxDQUFDLE1BQU0sQ0FBQzt3QkFDYixJQUFJO3dCQUNKLFNBQVMsRUFBRSxzQkFBc0I7cUJBQ2xDLENBQUMsQ0FBQTtnQkFDSixDQUFDO1lBQ0gsQ0FBQztTQUNGLENBQUE7SUFDSCxDQUFDO0NBQ0YsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRVNMaW50VXRpbHMgfSBmcm9tICdAdHlwZXNjcmlwdC1lc2xpbnQvdXRpbHMnXG5pbXBvcnQgeyBnZXRDYW5vblVybCwgZ2V0Q2Fub25QYXR0ZXJuIH0gZnJvbSAnLi4vdXRpbHMvY2Fub24uanMnXG5cbmNvbnN0IFJVTEVfTkFNRSA9ICduby1jcm9zcy16b25lLWltcG9ydHMnXG5jb25zdCBwYXR0ZXJuID0gZ2V0Q2Fub25QYXR0ZXJuKFJVTEVfTkFNRSlcblxuY29uc3QgY3JlYXRlUnVsZSA9IEVTTGludFV0aWxzLlJ1bGVDcmVhdG9yKCgpID0+IGdldENhbm9uVXJsKFJVTEVfTkFNRSkpXG5cbnR5cGUgTWVzc2FnZUlkcyA9ICdibG9ja3NJbXBvcnRCbG9ja3MnIHwgJ2NvbXBvbmVudHNJbXBvcnRCbG9ja3MnIHwgJ3J1bnRpbWVJbXBvcnRTY3JpcHRzJ1xuXG4vKipcbiAqIERldGVybWluZSB3aGljaCB6b25lIGEgZmlsZSBpcyBpbiBiYXNlZCBvbiBpdHMgcGF0aFxuICovXG5mdW5jdGlvbiBnZXRab25lKGZpbGVuYW1lOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKGZpbGVuYW1lLmluY2x1ZGVzKCcvYmxvY2tzLycpIHx8IGZpbGVuYW1lLmluY2x1ZGVzKCdcXFxcYmxvY2tzXFxcXCcpKSB7XG4gICAgcmV0dXJuICdibG9ja3MnXG4gIH1cbiAgaWYgKGZpbGVuYW1lLmluY2x1ZGVzKCcvY29tcG9uZW50cy8nKSB8fCBmaWxlbmFtZS5pbmNsdWRlcygnXFxcXGNvbXBvbmVudHNcXFxcJykpIHtcbiAgICByZXR1cm4gJ2NvbXBvbmVudHMnXG4gIH1cbiAgaWYgKGZpbGVuYW1lLmluY2x1ZGVzKCcvYXBwLycpIHx8IGZpbGVuYW1lLmluY2x1ZGVzKCdcXFxcYXBwXFxcXCcpKSB7XG4gICAgcmV0dXJuICdhcHAnXG4gIH1cbiAgaWYgKGZpbGVuYW1lLmluY2x1ZGVzKCcvaG9va3MvJykgfHwgZmlsZW5hbWUuaW5jbHVkZXMoJ1xcXFxob29rc1xcXFwnKSkge1xuICAgIHJldHVybiAnaG9va3MnXG4gIH1cbiAgaWYgKGZpbGVuYW1lLmluY2x1ZGVzKCcvdXRpbHMvJykgfHwgZmlsZW5hbWUuaW5jbHVkZXMoJ1xcXFx1dGlsc1xcXFwnKSkge1xuICAgIHJldHVybiAndXRpbHMnXG4gIH1cbiAgaWYgKGZpbGVuYW1lLmluY2x1ZGVzKCcvdG9vbHMvJykgfHwgZmlsZW5hbWUuaW5jbHVkZXMoJ1xcXFx0b29sc1xcXFwnKSkge1xuICAgIHJldHVybiAndG9vbHMnXG4gIH1cbiAgcmV0dXJuIG51bGxcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbiBpbXBvcnQgcGF0aCB0YXJnZXRzIGEgc3BlY2lmaWMgem9uZVxuICovXG5mdW5jdGlvbiBpbXBvcnRzWm9uZShpbXBvcnRQYXRoOiBzdHJpbmcsIHpvbmU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAvLyBIYW5kbGUgYWxpYXMgaW1wb3J0cyBsaWtlIEAvYmxvY2tzLy4uLiBvciBAL2NvbXBvbmVudHMvLi4uXG4gIGlmIChpbXBvcnRQYXRoLnN0YXJ0c1dpdGgoJ0AvJykpIHtcbiAgICByZXR1cm4gaW1wb3J0UGF0aC5zdGFydHNXaXRoKGBALyR7em9uZX0vYClcbiAgfVxuICAvLyBIYW5kbGUgcmVsYXRpdmUgaW1wb3J0c1xuICByZXR1cm4gaW1wb3J0UGF0aC5pbmNsdWRlcyhgLyR7em9uZX0vYCkgfHwgaW1wb3J0UGF0aC5pbmNsdWRlcyhgXFxcXCR7em9uZX1cXFxcYClcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbiBpbXBvcnQgdGFyZ2V0cyBfc2NyaXB0c1xuICovXG5mdW5jdGlvbiBpbXBvcnRzU2NyaXB0cyhpbXBvcnRQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBpbXBvcnRQYXRoLmluY2x1ZGVzKCdfc2NyaXB0cy8nKSB8fFxuICAgIGltcG9ydFBhdGguaW5jbHVkZXMoJ19zY3JpcHRzXFxcXCcpIHx8XG4gICAgaW1wb3J0UGF0aC5zdGFydHNXaXRoKCdAL19zY3JpcHRzLycpXG4gIClcbn1cblxuZXhwb3J0IGRlZmF1bHQgY3JlYXRlUnVsZTxbXSwgTWVzc2FnZUlkcz4oe1xuICBuYW1lOiBSVUxFX05BTUUsXG4gIG1ldGE6IHtcbiAgICB0eXBlOiAncHJvYmxlbScsXG4gICAgZG9jczoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIHBhdHRlcm4/LnN1bW1hcnkgfHwgJ0VuZm9yY2UgaW1wb3J0IGJvdW5kYXJpZXMgYmV0d2VlbiBDYW5vbiB6b25lcycsXG4gICAgfSxcbiAgICBtZXNzYWdlczoge1xuICAgICAgYmxvY2tzSW1wb3J0QmxvY2tzOiBgW0Nhbm9uICR7cGF0dGVybj8uaWQgfHwgJzAyMSd9XSBCbG9ja3MgY2Fubm90IGltcG9ydCBmcm9tIG90aGVyIGJsb2Nrcy4gRWFjaCBibG9jayBzaG91bGQgYmUgc2VsZi1jb250YWluZWQgb3IgaW1wb3J0IGZyb20gY29tcG9uZW50cy5gLFxuICAgICAgY29tcG9uZW50c0ltcG9ydEJsb2NrczogYFtDYW5vbiAke3BhdHRlcm4/LmlkIHx8ICcwMjEnfV0gQ29tcG9uZW50cyBjYW5ub3QgaW1wb3J0IGZyb20gYmxvY2tzLiBCbG9ja3MgY29tcG9zZSBjb21wb25lbnRzLCBub3QgdGhlIG90aGVyIHdheSBhcm91bmQuYCxcbiAgICAgIHJ1bnRpbWVJbXBvcnRTY3JpcHRzOiBgW0Nhbm9uICR7cGF0dGVybj8uaWQgfHwgJzAyMSd9XSBSdW50aW1lIGNvZGUgY2Fubm90IGltcG9ydCBmcm9tIF9zY3JpcHRzLy4gU2NyaXB0cyBhcmUgZm9yIGJ1aWxkLXRpbWUgb25seS5gLFxuICAgIH0sXG4gICAgc2NoZW1hOiBbXSxcbiAgfSxcbiAgZGVmYXVsdE9wdGlvbnM6IFtdLFxuICBjcmVhdGUoY29udGV4dCkge1xuICAgIGNvbnN0IGZpbGVuYW1lID0gY29udGV4dC5maWxlbmFtZSB8fCBjb250ZXh0LmdldEZpbGVuYW1lKClcbiAgICBjb25zdCBjdXJyZW50Wm9uZSA9IGdldFpvbmUoZmlsZW5hbWUpXG5cbiAgICAvLyBTa2lwIGZpbGVzIG5vdCBpbiBhIGtub3duIHpvbmVcbiAgICBpZiAoIWN1cnJlbnRab25lKSB7XG4gICAgICByZXR1cm4ge31cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgSW1wb3J0RGVjbGFyYXRpb24obm9kZSkge1xuICAgICAgICBjb25zdCBpbXBvcnRQYXRoID0gbm9kZS5zb3VyY2UudmFsdWUgYXMgc3RyaW5nXG5cbiAgICAgICAgLy8gUnVsZSAxOiBCbG9ja3MgY2Fubm90IGltcG9ydCBmcm9tIG90aGVyIGJsb2Nrc1xuICAgICAgICBpZiAoY3VycmVudFpvbmUgPT09ICdibG9ja3MnICYmIGltcG9ydHNab25lKGltcG9ydFBhdGgsICdibG9ja3MnKSkge1xuICAgICAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICBtZXNzYWdlSWQ6ICdibG9ja3NJbXBvcnRCbG9ja3MnLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICAvLyBSdWxlIDI6IENvbXBvbmVudHMgY2Fubm90IGltcG9ydCBmcm9tIGJsb2Nrc1xuICAgICAgICBpZiAoY3VycmVudFpvbmUgPT09ICdjb21wb25lbnRzJyAmJiBpbXBvcnRzWm9uZShpbXBvcnRQYXRoLCAnYmxvY2tzJykpIHtcbiAgICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgbWVzc2FnZUlkOiAnY29tcG9uZW50c0ltcG9ydEJsb2NrcycsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJ1bGUgMzogTm8gcnVudGltZSBjb2RlIGNhbiBpbXBvcnQgZnJvbSBfc2NyaXB0c1xuICAgICAgICBpZiAoaW1wb3J0c1NjcmlwdHMoaW1wb3J0UGF0aCkpIHtcbiAgICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgbWVzc2FnZUlkOiAncnVudGltZUltcG9ydFNjcmlwdHMnLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfVxuICB9LFxufSlcbiJdfQ==
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
import { getCanonUrl, getCanonPattern } from '../utils/canon.js';
|
|
3
|
+
const RULE_NAME = 'no-data-imports';
|
|
4
|
+
const pattern = getCanonPattern(RULE_NAME);
|
|
5
|
+
const createRule = ESLintUtils.RuleCreator(() => getCanonUrl(RULE_NAME));
|
|
6
|
+
/**
|
|
7
|
+
* Check if an import targets _data
|
|
8
|
+
*/
|
|
9
|
+
function importsData(importPath) {
|
|
10
|
+
return (importPath.includes('_data/') ||
|
|
11
|
+
importPath.includes('_data\\') ||
|
|
12
|
+
importPath.startsWith('@/_data/') ||
|
|
13
|
+
importPath === '_data' ||
|
|
14
|
+
importPath === '@/_data');
|
|
15
|
+
}
|
|
16
|
+
export default createRule({
|
|
17
|
+
name: RULE_NAME,
|
|
18
|
+
meta: {
|
|
19
|
+
type: 'problem',
|
|
20
|
+
docs: {
|
|
21
|
+
description: pattern?.summary ||
|
|
22
|
+
'Prevent runtime code from directly importing _data/ files',
|
|
23
|
+
},
|
|
24
|
+
messages: {
|
|
25
|
+
noDataImports: `[Canon ${pattern?.id || '022'}] Do not import directly from _data/. Use utility functions or fetch data through proper APIs. _data/ is for generated content only.`,
|
|
26
|
+
},
|
|
27
|
+
schema: [],
|
|
28
|
+
},
|
|
29
|
+
defaultOptions: [],
|
|
30
|
+
create(context) {
|
|
31
|
+
const filename = context.filename || context.getFilename();
|
|
32
|
+
// Allow _scripts to import from _data (they generate it)
|
|
33
|
+
if (filename.includes('_scripts/') || filename.includes('_scripts\\')) {
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
ImportDeclaration(node) {
|
|
38
|
+
const importPath = node.source.value;
|
|
39
|
+
if (importsData(importPath)) {
|
|
40
|
+
context.report({
|
|
41
|
+
node,
|
|
42
|
+
messageId: 'noDataImports',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tZGF0YS1pbXBvcnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VzbGludC9ydWxlcy9uby1kYXRhLWltcG9ydHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFBO0FBQ3RELE9BQU8sRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFFaEUsTUFBTSxTQUFTLEdBQUcsaUJBQWlCLENBQUE7QUFDbkMsTUFBTSxPQUFPLEdBQUcsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0FBRTFDLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUE7QUFJeEU7O0dBRUc7QUFDSCxTQUFTLFdBQVcsQ0FBQyxVQUFrQjtJQUNyQyxPQUFPLENBQ0wsVUFBVSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFDN0IsVUFBVSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFDOUIsVUFBVSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUM7UUFDakMsVUFBVSxLQUFLLE9BQU87UUFDdEIsVUFBVSxLQUFLLFNBQVMsQ0FDekIsQ0FBQTtBQUNILENBQUM7QUFFRCxlQUFlLFVBQVUsQ0FBaUI7SUFDeEMsSUFBSSxFQUFFLFNBQVM7SUFDZixJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUUsU0FBUztRQUNmLElBQUksRUFBRTtZQUNKLFdBQVcsRUFDVCxPQUFPLEVBQUUsT0FBTztnQkFDaEIsMkRBQTJEO1NBQzlEO1FBQ0QsUUFBUSxFQUFFO1lBQ1IsYUFBYSxFQUFFLFVBQVUsT0FBTyxFQUFFLEVBQUUsSUFBSSxLQUFLLHNJQUFzSTtTQUNwTDtRQUNELE1BQU0sRUFBRSxFQUFFO0tBQ1g7SUFDRCxjQUFjLEVBQUUsRUFBRTtJQUNsQixNQUFNLENBQUMsT0FBTztRQUNaLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBRTFELHlEQUF5RDtRQUN6RCxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ3RFLE9BQU8sRUFBRSxDQUFBO1FBQ1gsQ0FBQztRQUVELE9BQU87WUFDTCxpQkFBaUIsQ0FBQyxJQUFJO2dCQUNwQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQWUsQ0FBQTtnQkFFOUMsSUFBSSxXQUFXLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztvQkFDNUIsT0FBTyxDQUFDLE1BQU0sQ0FBQzt3QkFDYixJQUFJO3dCQUNKLFNBQVMsRUFBRSxlQUFlO3FCQUMzQixDQUFDLENBQUE7Z0JBQ0osQ0FBQztZQUNILENBQUM7U0FDRixDQUFBO0lBQ0gsQ0FBQztDQUNGLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEVTTGludFV0aWxzIH0gZnJvbSAnQHR5cGVzY3JpcHQtZXNsaW50L3V0aWxzJ1xuaW1wb3J0IHsgZ2V0Q2Fub25VcmwsIGdldENhbm9uUGF0dGVybiB9IGZyb20gJy4uL3V0aWxzL2Nhbm9uLmpzJ1xuXG5jb25zdCBSVUxFX05BTUUgPSAnbm8tZGF0YS1pbXBvcnRzJ1xuY29uc3QgcGF0dGVybiA9IGdldENhbm9uUGF0dGVybihSVUxFX05BTUUpXG5cbmNvbnN0IGNyZWF0ZVJ1bGUgPSBFU0xpbnRVdGlscy5SdWxlQ3JlYXRvcigoKSA9PiBnZXRDYW5vblVybChSVUxFX05BTUUpKVxuXG50eXBlIE1lc3NhZ2VJZHMgPSAnbm9EYXRhSW1wb3J0cydcblxuLyoqXG4gKiBDaGVjayBpZiBhbiBpbXBvcnQgdGFyZ2V0cyBfZGF0YVxuICovXG5mdW5jdGlvbiBpbXBvcnRzRGF0YShpbXBvcnRQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBpbXBvcnRQYXRoLmluY2x1ZGVzKCdfZGF0YS8nKSB8fFxuICAgIGltcG9ydFBhdGguaW5jbHVkZXMoJ19kYXRhXFxcXCcpIHx8XG4gICAgaW1wb3J0UGF0aC5zdGFydHNXaXRoKCdAL19kYXRhLycpIHx8XG4gICAgaW1wb3J0UGF0aCA9PT0gJ19kYXRhJyB8fFxuICAgIGltcG9ydFBhdGggPT09ICdAL19kYXRhJ1xuICApXG59XG5cbmV4cG9ydCBkZWZhdWx0IGNyZWF0ZVJ1bGU8W10sIE1lc3NhZ2VJZHM+KHtcbiAgbmFtZTogUlVMRV9OQU1FLFxuICBtZXRhOiB7XG4gICAgdHlwZTogJ3Byb2JsZW0nLFxuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBwYXR0ZXJuPy5zdW1tYXJ5IHx8XG4gICAgICAgICdQcmV2ZW50IHJ1bnRpbWUgY29kZSBmcm9tIGRpcmVjdGx5IGltcG9ydGluZyBfZGF0YS8gZmlsZXMnLFxuICAgIH0sXG4gICAgbWVzc2FnZXM6IHtcbiAgICAgIG5vRGF0YUltcG9ydHM6IGBbQ2Fub24gJHtwYXR0ZXJuPy5pZCB8fCAnMDIyJ31dIERvIG5vdCBpbXBvcnQgZGlyZWN0bHkgZnJvbSBfZGF0YS8uIFVzZSB1dGlsaXR5IGZ1bmN0aW9ucyBvciBmZXRjaCBkYXRhIHRocm91Z2ggcHJvcGVyIEFQSXMuIF9kYXRhLyBpcyBmb3IgZ2VuZXJhdGVkIGNvbnRlbnQgb25seS5gLFxuICAgIH0sXG4gICAgc2NoZW1hOiBbXSxcbiAgfSxcbiAgZGVmYXVsdE9wdGlvbnM6IFtdLFxuICBjcmVhdGUoY29udGV4dCkge1xuICAgIGNvbnN0IGZpbGVuYW1lID0gY29udGV4dC5maWxlbmFtZSB8fCBjb250ZXh0LmdldEZpbGVuYW1lKClcblxuICAgIC8vIEFsbG93IF9zY3JpcHRzIHRvIGltcG9ydCBmcm9tIF9kYXRhICh0aGV5IGdlbmVyYXRlIGl0KVxuICAgIGlmIChmaWxlbmFtZS5pbmNsdWRlcygnX3NjcmlwdHMvJykgfHwgZmlsZW5hbWUuaW5jbHVkZXMoJ19zY3JpcHRzXFxcXCcpKSB7XG4gICAgICByZXR1cm4ge31cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgSW1wb3J0RGVjbGFyYXRpb24obm9kZSkge1xuICAgICAgICBjb25zdCBpbXBvcnRQYXRoID0gbm9kZS5zb3VyY2UudmFsdWUgYXMgc3RyaW5nXG5cbiAgICAgICAgaWYgKGltcG9ydHNEYXRhKGltcG9ydFBhdGgpKSB7XG4gICAgICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgIG1lc3NhZ2VJZDogJ25vRGF0YUltcG9ydHMnLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfVxuICB9LFxufSlcbiJdfQ==
|
package/package.json
CHANGED
package/schema.json
CHANGED
|
@@ -230,6 +230,46 @@
|
|
|
230
230
|
"enforcement": "eslint",
|
|
231
231
|
"rule": "gallop/background-image-rounded",
|
|
232
232
|
"summary": "Background images must have rounded=\"rounded-none\""
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"id": "020",
|
|
236
|
+
"title": "No Arbitrary Colors",
|
|
237
|
+
"file": "patterns/020-no-arbitrary-colors.md",
|
|
238
|
+
"category": "styling",
|
|
239
|
+
"status": "stable",
|
|
240
|
+
"enforcement": "eslint",
|
|
241
|
+
"rule": "gallop/no-arbitrary-colors",
|
|
242
|
+
"summary": "Use defined color tokens, not arbitrary color values"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"id": "021",
|
|
246
|
+
"title": "Cross-Zone Import Boundaries",
|
|
247
|
+
"file": "patterns/021-cross-zone-imports.md",
|
|
248
|
+
"category": "structure",
|
|
249
|
+
"status": "stable",
|
|
250
|
+
"enforcement": "eslint",
|
|
251
|
+
"rule": "gallop/no-cross-zone-imports",
|
|
252
|
+
"summary": "Enforce import boundaries between Canon zones"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"id": "022",
|
|
256
|
+
"title": "No Data Direct Imports",
|
|
257
|
+
"file": "patterns/022-no-data-imports.md",
|
|
258
|
+
"category": "structure",
|
|
259
|
+
"status": "stable",
|
|
260
|
+
"enforcement": "eslint",
|
|
261
|
+
"rule": "gallop/no-data-imports",
|
|
262
|
+
"summary": "Prevent runtime code from importing _data/ directly"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"id": "023",
|
|
266
|
+
"title": "File Placement Authority",
|
|
267
|
+
"file": "patterns/023-file-placement.md",
|
|
268
|
+
"category": "structure",
|
|
269
|
+
"status": "stable",
|
|
270
|
+
"enforcement": "cli",
|
|
271
|
+
"rule": "gallop validate",
|
|
272
|
+
"summary": "All files must be in Canon-defined zones"
|
|
233
273
|
}
|
|
234
274
|
],
|
|
235
275
|
"guarantees": [
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Speedwell template configuration for ESLint flat config
|
|
3
|
-
* Enables all Gallop rules relevant to the Speedwell architecture
|
|
4
|
-
*/
|
|
5
|
-
declare const speedwellRules: {
|
|
6
|
-
readonly 'gallop/no-client-blocks': "warn";
|
|
7
|
-
readonly 'gallop/no-container-in-section': "warn";
|
|
8
|
-
readonly 'gallop/prefer-component-props': "warn";
|
|
9
|
-
readonly 'gallop/prefer-typography-components': "warn";
|
|
10
|
-
readonly 'gallop/prefer-layout-components': "warn";
|
|
11
|
-
readonly 'gallop/background-image-rounded': "warn";
|
|
12
|
-
};
|
|
13
|
-
export default speedwellRules;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Speedwell template configuration for ESLint flat config
|
|
3
|
-
* Enables all Gallop rules relevant to the Speedwell architecture
|
|
4
|
-
*/
|
|
5
|
-
const speedwellRules = {
|
|
6
|
-
// Blocks should be server components - extract client logic to components
|
|
7
|
-
'gallop/no-client-blocks': 'warn',
|
|
8
|
-
// Section already provides containment
|
|
9
|
-
'gallop/no-container-in-section': 'warn',
|
|
10
|
-
// Use component props instead of className for style values
|
|
11
|
-
'gallop/prefer-component-props': 'warn',
|
|
12
|
-
// Use Typography components instead of raw p/span tags
|
|
13
|
-
'gallop/prefer-typography-components': 'warn',
|
|
14
|
-
// Use Grid/Columns instead of raw div with grid classes
|
|
15
|
-
'gallop/prefer-layout-components': 'warn',
|
|
16
|
-
// Background images must have rounded="rounded-none"
|
|
17
|
-
'gallop/background-image-rounded': 'warn',
|
|
18
|
-
};
|
|
19
|
-
export default speedwellRules;
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlZWR3ZWxsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VzbGludC9jb25maWdzL3NwZWVkd2VsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFDSCxNQUFNLGNBQWMsR0FBRztJQUNyQiwwRUFBMEU7SUFDMUUseUJBQXlCLEVBQUUsTUFBTTtJQUVqQyx1Q0FBdUM7SUFDdkMsZ0NBQWdDLEVBQUUsTUFBTTtJQUV4Qyw0REFBNEQ7SUFDNUQsK0JBQStCLEVBQUUsTUFBTTtJQUV2Qyx1REFBdUQ7SUFDdkQscUNBQXFDLEVBQUUsTUFBTTtJQUU3Qyx3REFBd0Q7SUFDeEQsaUNBQWlDLEVBQUUsTUFBTTtJQUV6QyxxREFBcUQ7SUFDckQsaUNBQWlDLEVBQUUsTUFBTTtDQUNqQyxDQUFBO0FBRVYsZUFBZSxjQUFjLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNwZWVkd2VsbCB0ZW1wbGF0ZSBjb25maWd1cmF0aW9uIGZvciBFU0xpbnQgZmxhdCBjb25maWdcbiAqIEVuYWJsZXMgYWxsIEdhbGxvcCBydWxlcyByZWxldmFudCB0byB0aGUgU3BlZWR3ZWxsIGFyY2hpdGVjdHVyZVxuICovXG5jb25zdCBzcGVlZHdlbGxSdWxlcyA9IHtcbiAgLy8gQmxvY2tzIHNob3VsZCBiZSBzZXJ2ZXIgY29tcG9uZW50cyAtIGV4dHJhY3QgY2xpZW50IGxvZ2ljIHRvIGNvbXBvbmVudHNcbiAgJ2dhbGxvcC9uby1jbGllbnQtYmxvY2tzJzogJ3dhcm4nLFxuXG4gIC8vIFNlY3Rpb24gYWxyZWFkeSBwcm92aWRlcyBjb250YWlubWVudFxuICAnZ2FsbG9wL25vLWNvbnRhaW5lci1pbi1zZWN0aW9uJzogJ3dhcm4nLFxuXG4gIC8vIFVzZSBjb21wb25lbnQgcHJvcHMgaW5zdGVhZCBvZiBjbGFzc05hbWUgZm9yIHN0eWxlIHZhbHVlc1xuICAnZ2FsbG9wL3ByZWZlci1jb21wb25lbnQtcHJvcHMnOiAnd2FybicsXG5cbiAgLy8gVXNlIFR5cG9ncmFwaHkgY29tcG9uZW50cyBpbnN0ZWFkIG9mIHJhdyBwL3NwYW4gdGFnc1xuICAnZ2FsbG9wL3ByZWZlci10eXBvZ3JhcGh5LWNvbXBvbmVudHMnOiAnd2FybicsXG5cbiAgLy8gVXNlIEdyaWQvQ29sdW1ucyBpbnN0ZWFkIG9mIHJhdyBkaXYgd2l0aCBncmlkIGNsYXNzZXNcbiAgJ2dhbGxvcC9wcmVmZXItbGF5b3V0LWNvbXBvbmVudHMnOiAnd2FybicsXG5cbiAgLy8gQmFja2dyb3VuZCBpbWFnZXMgbXVzdCBoYXZlIHJvdW5kZWQ9XCJyb3VuZGVkLW5vbmVcIlxuICAnZ2FsbG9wL2JhY2tncm91bmQtaW1hZ2Utcm91bmRlZCc6ICd3YXJuJyxcbn0gYXMgY29uc3RcblxuZXhwb3J0IGRlZmF1bHQgc3BlZWR3ZWxsUnVsZXNcbiJdfQ==
|