From 3d9acf8102e51d704c7b5564cba66a37255d2f8e Mon Sep 17 00:00:00 2001 From: Maciej Krajowski-Kukiel Date: Mon, 11 May 2026 15:16:52 +0200 Subject: [PATCH] improve finding platformos files --- .backlog/config.yml | 14 +++++ ..._PHYSICAL_PATH-regexps-in-path-utils.ts.md | 38 ++++++++++++ ...alar-pattern-ActivityStreams-file-types.md | 44 +++++++++++++ ...isSupportedSourceFile-to-be-type-driven.md | 48 ++++++++++++++ ...sion-filters-with-isSupportedSourceFile.md | 53 ++++++++++++++++ ...-utils-spec-for-backend-mirror-behavior.md | 62 +++++++++++++++++++ ...-build-test-pass-fix-downstream-fallout.md | 45 ++++++++++++++ CLAUDE.md | 29 +++++++++ .../platformos-check-common/src/find-root.ts | 19 +++++- packages/platformos-check-common/src/index.ts | 2 + .../data/latest.json | 2 +- .../src/find-root.spec.ts | 37 +++++++++++ .../platformos-check-node/src/index.spec.ts | 14 ++--- packages/platformos-check-node/src/index.ts | 12 +++- packages/platformos-common/src/path-utils.ts | 36 +++++++++++ .../providers/FixAllProvider.spec.ts | 4 +- .../codeActions/providers/FixProvider.spec.ts | 4 +- .../providers/SuggestionProvider.spec.ts | 4 +- .../providers/ApplyFixesProvider.spec.ts | 4 +- .../providers/ApplySuggestionProvider.spec.ts | 4 +- .../providers/RunChecksProvider.spec.ts | 4 +- .../params/LiquidCompletionParams.spec.ts | 4 +- .../ObjectCompletionProvider.spec.ts | 5 +- ...ranslationStringDefinitionProvider.spec.ts | 4 +- ...lTagNameDocumentHighlightsProvider.spec.ts | 10 +-- ...BlockTagDocumentHighlightsProvider.spec.ts | 12 ++-- .../DocumentLinksProvider.spec.ts | 2 +- .../src/documents/DocumentManager.ts | 6 +- ...utoclosingOnTypeFormattingProvider.spec.ts | 8 +-- ...utoclosingOnTypeFormattingProvider.spec.ts | 2 +- .../LiquidObjectHoverProvider.spec.ts | 5 +- .../EmptyHtmlTagLinkedRangesProvider.spec.ts | 8 +-- .../HtmlTagNameLinkedRangesProvider.spec.ts | 2 +- .../HtmlTagNameRenameProvider.spec.ts | 6 +- .../src/test/CompletionItemsAssertion.ts | 4 +- .../src/test/HoverAssertion.ts | 4 +- 36 files changed, 502 insertions(+), 59 deletions(-) create mode 100644 .backlog/config.yml create mode 100644 .backlog/tasks/task-1 - Mirror-backend-FULL_PHYSICAL_PATH-regexps-in-path-utils.ts.md create mode 100644 .backlog/tasks/task-2 - Add-scalar-pattern-ActivityStreams-file-types.md create mode 100644 .backlog/tasks/task-3 - Rewrite-isSupportedSourceFile-to-be-type-driven.md create mode 100644 .backlog/tasks/task-4 - Replace-inlined-extension-filters-with-isSupportedSourceFile.md create mode 100644 .backlog/tasks/task-5 - Update-path-utils-spec-for-backend-mirror-behavior.md create mode 100644 .backlog/tasks/task-6 - Full-build-test-pass-fix-downstream-fallout.md diff --git a/.backlog/config.yml b/.backlog/config.yml new file mode 100644 index 00000000..4da91d7f --- /dev/null +++ b/.backlog/config.yml @@ -0,0 +1,14 @@ +project_name: "platformos-tools" +default_status: "To Do" +statuses: ["To Do", "In Progress", "Done"] +labels: [] +date_format: yyyy-mm-dd +max_column_width: 20 +auto_open_browser: true +default_port: 6420 +remote_operations: true +auto_commit: false +bypass_git_hooks: false +check_active_branches: true +active_branch_days: 30 +task_prefix: "task" diff --git a/.backlog/tasks/task-1 - Mirror-backend-FULL_PHYSICAL_PATH-regexps-in-path-utils.ts.md b/.backlog/tasks/task-1 - Mirror-backend-FULL_PHYSICAL_PATH-regexps-in-path-utils.ts.md new file mode 100644 index 00000000..852e3547 --- /dev/null +++ b/.backlog/tasks/task-1 - Mirror-backend-FULL_PHYSICAL_PATH-regexps-in-path-utils.ts.md @@ -0,0 +1,38 @@ +--- +id: TASK-1 +title: Mirror backend FULL_PHYSICAL_PATH regexps in path-utils.ts +status: To Do +assignee: [] +created_date: '2026-05-11 12:48' +labels: [] +dependencies: [] +--- + +## Description + + +Replace the current FILE_TYPE_DIRS + TYPE_MATCHERS in `packages/platformos-common/src/path-utils.ts` with a declarative table that is a 1:1 mirror of the backend `converters_config.rb` regexps. The linter must classify a file iff the backend would dispatch that file to a converter. + +**Source of truth:** `desksnearme/app/services/app_builder/services/converters_config.rb` plus per-model `PATH_DIRECTORY` / `EXTENSION` / `PHYSICAL_PATH` constants under `desksnearme/app/models/`. Helpful header is `desksnearme/app/models/concerns/deployable.rb` (lines 20–22) which builds `FULL_PHYSICAL_PATH = \A + DIR_PREFIX + PHYSICAL_PATH`. + +**Scope:** +- Drop `marketplace_builder` support entirely (user-approved). Only `app/` and `modules/{name}/{access}/` (plus optional `app/modules/{name}/{access}/`). +- Replace the dir-name-only matchers with full FULL_PHYSICAL_PATH regexps. This catches wrong extensions (e.g. `app/translations/en.json` → undefined) the way the backend does. +- Keep `getFileType`, `getAppPaths`, `getModulePaths` signatures stable; re-derive their data from a single `BACKEND_MODELS` table. +- Mirror backend quirks verbatim with `// backend quirk:` comments: GraphQuery `(graph_queries|graphql)s?` and DIR_PREFIX `modules/(.+)(private|public)/` missing-slash shape. +- Update `RouteTable.extractRelativePagePath` to drop the `marketplace_builder` alternative. + +**Files:** +- `packages/platformos-common/src/path-utils.ts` +- `packages/platformos-common/src/route-table/RouteTable.ts` (drop `marketplace_builder` from regex) +- `packages/platformos-common/CLAUDE.md` (update architecture note) + + +## Acceptance Criteria + +- [ ] #1 BACKEND_MODELS table mirrors every row in converters_config.rb (Page, InstanceView Page/Layout/Partial split, GraphQuery, AuthorizationPolicy, EmailNotification, ApiCallNotification, SmsNotification, DataMigration, FormConfiguration, Translation, TransactableType, CustomModelType, InstanceProfileType, Asset) +- [ ] #2 DIR_PREFIX accepts only: empty | app/ | modules/{name}/{public|private}/ | app/modules/{name}/{public|private}/. marketplace_builder removed everywhere +- [ ] #3 FULL_PHYSICAL_PATH regex includes the extension suffix where the backend enforces it (.liquid for Liquid types, .graphql for GraphQL, .yml for YAML types) +- [ ] #4 Each BACKEND_MODELS row carries a comment pointing to the exact backend model file:line it mirrors +- [ ] #5 RouteTable.extractRelativePagePath drops the marketplace_builder regex alternative + diff --git a/.backlog/tasks/task-2 - Add-scalar-pattern-ActivityStreams-file-types.md b/.backlog/tasks/task-2 - Add-scalar-pattern-ActivityStreams-file-types.md new file mode 100644 index 00000000..f7368872 --- /dev/null +++ b/.backlog/tasks/task-2 - Add-scalar-pattern-ActivityStreams-file-types.md @@ -0,0 +1,44 @@ +--- +id: TASK-2 +title: Add scalar-pattern + ActivityStreams file types +status: To Do +assignee: [] +created_date: '2026-05-11 13:02' +labels: [] +dependencies: + - TASK-1 +--- + +## Description + + +Add new `PlatformOSFileType` enum values for files that converters_config.rb matches with scalar/literal patterns rather than per-model FULL_PHYSICAL_PATH, plus the two ActivityStreams subtypes the backend dispatches. + +**New enum values:** +- `InstanceConfig` — `^/?(app/)?config\.yml$` (drops marketplace_builder) +- `UserType` — `\A(app/)?user\.yml` +- `AssetManifest` — `\A(app/)?asset_manifest\.json` +- `AssetsManifest` — `\A(app/|modules/(.+)(private|public)/)assets\.json` +- `ModulesLock` — `^/?(?:(?:app/)?pos-modules\.lock\.json|pos-module\.lock\.json)$` +- `ActivityStreamsHandler` — `activity_streams/handlers/(.+)\.yml` +- `ActivityStreamsGroupingHandler` — `activity_streams/grouping_handlers/(.+)\.yml` + +**Source:** `converters_config.rb` lines 7–22 (scalar patterns) plus `app/models/activity_streams/handler.rb` and `app/models/activity_streams/grouping_handler.rb`. + +**Design notes:** +- ActivityStreams types extend the `BACKEND_MODELS` table from task 1 (they have normal `PHYSICAL_PATH`). +- Scalar patterns live in a small separate `SCALAR_MATCHERS` table. `getFileType` consults `TYPE_MATCHERS` first, then `SCALAR_MATCHERS`. +- Add `ActivityStreamsHandler` and `ActivityStreamsGroupingHandler` to `YAML_FILE_TYPES`. +- Scalar JSON types (`AssetManifest`, `AssetsManifest`, `ModulesLock`) get classified but are NOT in `YAML_FILE_TYPES` — `isSupportedSourceFile` returns false for them (no JSON checks yet). + +**Files:** +- `packages/platformos-common/src/path-utils.ts` + + +## Acceptance Criteria + +- [ ] #1 Seven new PlatformOSFileType enum values added with backend file:line references +- [ ] #2 getFileType correctly classifies: config.yml, app/config.yml, user.yml, app/user.yml, asset_manifest.json, app/asset_manifest.json, app/assets.json, modules/core/public/assets.json, pos-modules.lock.json, pos-module.lock.json, app/pos-modules.lock.json +- [ ] #3 ActivityStreamsHandler and ActivityStreamsGroupingHandler classify under app/, modules/, and app/modules/ roots +- [ ] #4 YAML_FILE_TYPES set updated to include ActivityStreamsHandler and ActivityStreamsGroupingHandler + diff --git a/.backlog/tasks/task-3 - Rewrite-isSupportedSourceFile-to-be-type-driven.md b/.backlog/tasks/task-3 - Rewrite-isSupportedSourceFile-to-be-type-driven.md new file mode 100644 index 00000000..a6886578 --- /dev/null +++ b/.backlog/tasks/task-3 - Rewrite-isSupportedSourceFile-to-be-type-driven.md @@ -0,0 +1,48 @@ +--- +id: TASK-3 +title: Rewrite isSupportedSourceFile to be type-driven +status: To Do +assignee: [] +created_date: '2026-05-11 13:09' +labels: [] +dependencies: + - TASK-2 +--- + +## Description + + +Stop dispatching `isSupportedSourceFile` on file extension first. The current implementation in `packages/platformos-common/src/path-utils.ts` (line 273) duplicates type-membership decisions across three branches. After tasks 1+2 land, replace it with a single type-driven decision that defers to `getFileType` and the LIQUID/GRAPHQL/YAML sets. + +**Target behavior:** +```ts +export function isSupportedSourceFile(uri: UriString): boolean { + // Asset partials are compiled by the backend but the linter cannot parse + // them as Liquid — they are CSS/JS/SCSS templates. + if (/\.(?:s?css|js)\.liquid$/.test(uri)) return false; + const type = getFileType(uri); + if (type === undefined) return false; + if (LIQUID_FILE_TYPES.has(type)) return uri.endsWith('.liquid'); + if (GRAPHQL_FILE_TYPES.has(type)) return true; // extension enforced by FULL_PHYSICAL_PATH + if (YAML_FILE_TYPES.has(type)) return true; // extension enforced by FULL_PHYSICAL_PATH + return false; // Asset, scalar JSON types, etc. +} +``` + +**Why the `.liquid` gate stays for Liquid types:** backend `PHYSICAL_PATH` for `Page` and `InstanceView` accepts any extension (`(.+)` with no `\.liquid\z` anchor), so the regex alone is not enough to know whether the linter can parse it. + +**Why GraphQL/YAML don't need an extension gate:** their FULL_PHYSICAL_PATH already enforces `\.graphql\z` or `\.yml\z`. + +**Files:** +- `packages/platformos-common/src/path-utils.ts` + +**Optional cleanup:** `isKnownLiquidFile`, `isKnownGraphQLFile`, `isKnownYAMLFile` become thin wrappers over `getFileType` + a type-set lookup. Keep exported for back-compat; mark `isSupportedSourceFile` as preferred. + + +## Acceptance Criteria + +- [ ] #1 isSupportedSourceFile uses getFileType + type-set membership; no extension-based dispatch except the asset-partial skip and the Page/InstanceView .liquid gate +- [ ] #2 Returns false for Asset, AssetManifest, AssetsManifest, ModulesLock, InstanceConfig, UserType +- [ ] #3 Returns false for app/views/partials/foo.css.liquid (asset partial in known dir) +- [ ] #4 Returns true for app/views/pages/home.liquid and false for app/views/pages/home.txt + diff --git a/.backlog/tasks/task-4 - Replace-inlined-extension-filters-with-isSupportedSourceFile.md b/.backlog/tasks/task-4 - Replace-inlined-extension-filters-with-isSupportedSourceFile.md new file mode 100644 index 00000000..2753c84e --- /dev/null +++ b/.backlog/tasks/task-4 - Replace-inlined-extension-filters-with-isSupportedSourceFile.md @@ -0,0 +1,53 @@ +--- +id: TASK-4 +title: Replace inlined extension filters with isSupportedSourceFile +status: To Do +assignee: [] +created_date: '2026-05-11 13:10' +labels: [] +dependencies: + - TASK-3 +--- + +## Description + + +Now that `isSupportedSourceFile` is the single source of truth (task 3), eliminate the two callers that hand-roll a subset of its logic. + +**Caller 1 — `packages/platformos-check-node/src/index.ts:144-163`** + +Current code inside `getApp().glob().filter(...)`: +```ts +if (filePath.endsWith('.liquid') && !isKnownLiquidFile(filePath)) return false; +if (filePath.endsWith('.graphql') && !isKnownGraphQLFile(filePath)) return false; +if ((filePath.endsWith('.yml') || filePath.endsWith('.yaml')) && !isKnownYAMLFile(filePath)) return false; +return true; +``` +Replace with: +```ts +if (!isSupportedSourceFile(filePath)) return false; +return true; +``` +Also drop the now-unused `isKnownLiquidFile`, `isKnownGraphQLFile`, `isKnownYAMLFile` imports. + +**Caller 2 — `packages/platformos-language-server-common/src/documents/DocumentManager.ts:84-89`** + +Current: +```ts +.filter(sourceCode => sourceCode.type !== SourceCodeType.LiquidHtml || isKnownLiquidFile(sourceCode.uri)) +``` +This only filters Liquid; GraphQL and YAML files outside known dirs slip through. Replace with `isSupportedSourceFile(sourceCode.uri)` so the LSP `app()` view matches what the CLI sees. + +**Behavior change to note:** `DocumentManager.app()` will now drop graphql/yaml files that sit outside known dirs. If any LSP test depends on a misplaced fixture being included, update the fixture path. + +**Files:** +- `packages/platformos-check-node/src/index.ts` +- `packages/platformos-language-server-common/src/documents/DocumentManager.ts` + + +## Acceptance Criteria + +- [ ] #1 platformos-check-node/src/index.ts uses isSupportedSourceFile and drops the three isKnown* imports +- [ ] #2 DocumentManager.app() uses isSupportedSourceFile uniformly +- [ ] #3 yarn build succeeds for both packages with no unused-import errors + diff --git a/.backlog/tasks/task-5 - Update-path-utils-spec-for-backend-mirror-behavior.md b/.backlog/tasks/task-5 - Update-path-utils-spec-for-backend-mirror-behavior.md new file mode 100644 index 00000000..c946da85 --- /dev/null +++ b/.backlog/tasks/task-5 - Update-path-utils-spec-for-backend-mirror-behavior.md @@ -0,0 +1,62 @@ +--- +id: TASK-5 +title: Update path-utils spec for backend-mirror behavior +status: To Do +assignee: [] +created_date: '2026-05-11 13:10' +labels: [] +dependencies: + - TASK-3 +--- + +## Description + + +Rewrite `packages/platformos-common/src/path-utils.spec.ts` to assert the new (stricter, backend-exact) semantics. + +**Remove:** +- The entire `describe('marketplace_builder/ legacy root', ...)` block. +- All other `marketplace_builder/...` assertions sprinkled through other describes (search for the literal string). + +**Add coverage for new behavior:** +- Wrong-extension rejection now that the regex includes the extension suffix: + - `app/translations/en.json` → `getFileType` undefined + - `app/graphql/x.txt` → undefined + - `app/transactable_types/x.yml.bak` → undefined + - `app/authorization_policies/x.txt` → undefined +- Scalar patterns (from task 2): + - `config.yml`, `app/config.yml` → `InstanceConfig` + - `user.yml`, `app/user.yml` → `UserType` + - `app/asset_manifest.json` → `AssetManifest` + - `app/assets.json`, `modules/core/public/assets.json` → `AssetsManifest` + - `pos-modules.lock.json`, `app/pos-modules.lock.json`, `pos-module.lock.json` → `ModulesLock` +- ActivityStreams: + - `app/activity_streams/handlers/x.yml` → `ActivityStreamsHandler` + - `app/activity_streams/grouping_handlers/x.yml` → `ActivityStreamsGroupingHandler` + - Module versions of the same +- Page/InstanceView with non-`.liquid` extension: + - `app/views/pages/home.html` → `getFileType` returns `Page`, `isSupportedSourceFile` returns `false` +- Asset partials in known dirs: + - `app/views/partials/foo.css.liquid` → `isSupportedSourceFile` returns `false` + - `app/views/partials/foo.js.liquid` → `isSupportedSourceFile` returns `false` +- Backend quirks (mirror verbatim, document with comment): + - `app/graphqls/x.graphql` → `GraphQL` (the `s?` quirk) + +**Existing spec sections to keep/adjust:** +- `app/ root — *` describes — keep as is +- `module paths` describe — keep +- `app/modules nested paths` describe — keep +- `false positive prevention` describe — keep all cases +- `getAppPaths` / `getModulePaths` describes — keep +- Convenience predicates — drop the `marketplace_builder/...` assertions inside them + +**Files:** +- `packages/platformos-common/src/path-utils.spec.ts` + + +## Acceptance Criteria + +- [ ] #1 All marketplace_builder/ assertions removed +- [ ] #2 Scalar-pattern, ActivityStreams, wrong-extension, asset-partial, and Page-non-liquid cases added +- [ ] #3 yarn workspace @platformos/platformos-common test passes + diff --git a/.backlog/tasks/task-6 - Full-build-test-pass-fix-downstream-fallout.md b/.backlog/tasks/task-6 - Full-build-test-pass-fix-downstream-fallout.md new file mode 100644 index 00000000..635e4a6b --- /dev/null +++ b/.backlog/tasks/task-6 - Full-build-test-pass-fix-downstream-fallout.md @@ -0,0 +1,45 @@ +--- +id: TASK-6 +title: Full build + test pass; fix downstream fallout +status: To Do +assignee: [] +created_date: '2026-05-11 13:12' +labels: [] +dependencies: + - TASK-4 + - TASK-5 +--- + +## Description + + +After tasks 1–5 land, run the full monorepo build and test suite, and fix any breakage caused by: + +- Stricter regex (extension-anchored) classification +- `marketplace_builder/` removal — any fixture, snapshot, or spec using that root must be migrated to `app/` or deleted +- `DocumentManager.app()` now filtering graphql/yaml strictly — LSP specs may have fixtures in non-canonical dirs + +**Commands:** +```bash +NPM_TOKEN=dummy yarn build +NPM_TOKEN=dummy yarn test +yarn type-check +``` + +**Likely fallout to expect:** +- `platformos-language-server-common/src/**/*.spec.ts` — fixtures may use `marketplace_builder/` paths +- `platformos-check-common/src/**/*.spec.ts` — likewise +- Snapshot mismatches from the URI-classification change + +**Files (anticipated, not exhaustive):** +- Anything that grep `marketplace_builder` still finds under `packages/` +- Anything that grep `isKnownLiquidFile\|isKnownGraphQLFile\|isKnownYAMLFile` outside path-utils still finds (might be more callers we missed) + + +## Acceptance Criteria + +- [ ] #1 yarn build succeeds with zero TypeScript errors +- [ ] #2 yarn test passes (all 239 test files, 1576+ individual tests) +- [ ] #3 yarn type-check passes +- [ ] #4 grep -rn marketplace_builder packages/ --include=*.ts returns no live (non-comment) hits + diff --git a/CLAUDE.md b/CLAUDE.md index 7d792ac5..a27d4ff0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -151,3 +151,32 @@ export SHOPIFY_TLD_ROOT=/path/to/theme-liquid-docs theme-docs download code . ``` + + + + + +## BACKLOG WORKFLOW INSTRUCTIONS + +This project uses Backlog.md MCP for all task and project management activities. + +**CRITICAL GUIDANCE** + +- If your client supports MCP resources, read `backlog://workflow/overview` to understand when and how to use Backlog for this project. +- If your client only supports tools or the above request fails, call `backlog.get_backlog_instructions()` to load the tool-oriented overview. Use the `instruction` selector when you need `task-creation`, `task-execution`, or `task-finalization`. + +- **First time working here?** Read the overview resource IMMEDIATELY to learn the workflow +- **Already familiar?** You should have the overview cached ("## Backlog.md Overview (MCP)") +- **When to read it**: BEFORE creating tasks, or when you're unsure whether to track work + +These guides cover: +- Decision framework for when to create tasks +- Search-first workflow to avoid duplicates +- Links to detailed guides for task creation, execution, and finalization +- MCP tools reference + +You MUST read the overview resource to understand the complete workflow. The information is NOT summarized here. + + + + diff --git a/packages/platformos-check-common/src/find-root.ts b/packages/platformos-check-common/src/find-root.ts index 23640b13..20818c09 100644 --- a/packages/platformos-check-common/src/find-root.ts +++ b/packages/platformos-check-common/src/find-root.ts @@ -3,13 +3,28 @@ import * as path from './path'; type FileExists = (uri: string) => Promise; +function isInsideApp(dir: UriString): boolean { + let current = dir; + while (true) { + const parent = path.dirname(current); + if (parent === current) return false; + if (path.basename(parent) === 'app') return true; + current = parent; + } +} + async function isRoot(dir: UriString, fileExists: FileExists) { return or( fileExists(path.join(dir, '.pos')), fileExists(path.join(dir, '.platformos-check.yml')), fileExists(path.join(dir, 'app')), - // modules/ is a root indicator only when not inside app/ (app/modules/ is a valid subdirectory) - and(fileExists(path.join(dir, 'modules')), Promise.resolve(path.basename(dir) !== 'app')), + // modules/ is a root indicator only when not inside an app/ subtree. + // app/modules/ is a valid subdirectory, and app/views/partials/modules/ is a + // legitimate partial organization that should not be mistaken for a project root. + and( + fileExists(path.join(dir, 'modules')), + Promise.resolve(path.basename(dir) !== 'app' && !isInsideApp(dir)), + ), ); } diff --git a/packages/platformos-check-common/src/index.ts b/packages/platformos-check-common/src/index.ts index eb9fee4d..38c4bfb2 100644 --- a/packages/platformos-check-common/src/index.ts +++ b/packages/platformos-check-common/src/index.ts @@ -60,11 +60,13 @@ export { isFormConfiguration, isKnownGraphQLFile, isKnownLiquidFile, + isKnownYAMLFile, isLayout, isMigration, isPage, isPartial, isSms, + isSupportedSourceFile, PlatformOSFileType, } from '@platformos/platformos-common'; export * from './frontmatter'; diff --git a/packages/platformos-check-docs-updater/data/latest.json b/packages/platformos-check-docs-updater/data/latest.json index 4b059ad2..b90959cb 100644 --- a/packages/platformos-check-docs-updater/data/latest.json +++ b/packages/platformos-check-docs-updater/data/latest.json @@ -1,2 +1,2 @@ -{"revision":"05ac4637cfd868fd7f72e2a1ebf40fc93428e114"} +{"revision":"30103f74fe1f031dc5aec3a8f0608339bd2b858d"} diff --git a/packages/platformos-check-node/src/find-root.spec.ts b/packages/platformos-check-node/src/find-root.spec.ts index b2f57799..2b1b36e7 100644 --- a/packages/platformos-check-node/src/find-root.spec.ts +++ b/packages/platformos-check-node/src/find-root.spec.ts @@ -124,4 +124,41 @@ describe('Unit: findRoot', () => { expect(root).toBe(workspace.uri('.')); }); }); + + describe('with partials organized under a modules/ subdirectory', () => { + let workspace: Workspace; + + beforeAll(async () => { + // Real-world structure: partials grouped by module name under + // app/views/partials/modules/. This must NOT be treated as a project root. + workspace = await makeTempWorkspace({ + app: { + views: { + partials: { + modules: { + foo: { + 'bar.liquid': '', + }, + }, + baz: { + 'qux.liquid': '', + }, + }, + }, + }, + }); + }); + + afterAll(async () => { + await workspace.clean(); + }); + + it('walks past app/views/partials/ even when a modules/ subdir exists there', async () => { + const root = await findRoot( + workspace.uri('app/views/partials/baz/qux.liquid'), + fileExists, + ); + expect(root).toBe(workspace.uri('.')); + }); + }); }); diff --git a/packages/platformos-check-node/src/index.spec.ts b/packages/platformos-check-node/src/index.spec.ts index 2c2e1303..2ed68718 100644 --- a/packages/platformos-check-node/src/index.spec.ts +++ b/packages/platformos-check-node/src/index.spec.ts @@ -9,10 +9,10 @@ describe('Unit: getApp', () => { beforeEach(async () => { workspace = await makeTempWorkspace({ - locales: { - 'en.default.json': '{}', - }, app: { + translations: { + 'en.yml': 'en:\n hello: Hello', + }, views: { partials: { 'header.liquid': '', @@ -34,13 +34,13 @@ describe('Unit: getApp', () => { }; const app = await getApp(config); - const jsonFile = app.find((sc) => sc.type === SourceCodeType.JSON); - assert(jsonFile); + const yamlFile = app.find((sc) => sc.type === SourceCodeType.YAML); + assert(yamlFile); // internally we expect the path to be normalized // Use .replace() instead of normalize-path here because this is a URI (file:///...), // not a filesystem path — normalize-path would collapse the triple slash. - expect(jsonFile.uri).to.equal(workspace.uri('locales/en.default.json').replace(/\\/g, '/')); + expect(yamlFile.uri).to.equal(workspace.uri('app/translations/en.yml').replace(/\\/g, '/')); }); }); @@ -51,6 +51,6 @@ describe('Unit: getAppFilesPathPattern', () => { const rootUri = pathToFileURL(__dirname); const normalizedGlob = getAppFilesPathPattern(rootUri.toString()); - expect(normalizedGlob).to.equal(normalize(__dirname) + '/**/*.{liquid,json,graphql,yml,yaml}'); + expect(normalizedGlob).to.equal(normalize(__dirname) + '/**/*.{liquid,graphql,yml,yaml}'); }); }); diff --git a/packages/platformos-check-node/src/index.ts b/packages/platformos-check-node/src/index.ts index 6c188f93..e134a564 100644 --- a/packages/platformos-check-node/src/index.ts +++ b/packages/platformos-check-node/src/index.ts @@ -14,6 +14,7 @@ import { isIgnored, isKnownLiquidFile, isKnownGraphQLFile, + isKnownYAMLFile, memo, path as pathUtils, YAMLSourceCode, @@ -149,6 +150,15 @@ export async function getApp(config: Config): Promise { // Only lint .graphql files that belong to a recognized platformOS GraphQL directory. // Schema files, generator templates (e.g. ERB .graphql), etc. are excluded. if (filePath.endsWith('.graphql') && !isKnownGraphQLFile(filePath)) return false; + // Only lint .yml/.yaml files that belong to a recognized platformOS YAML + // directory (translations, custom model types, etc.). Config files like + // config.yml or .platformos-check.yml are excluded. + if ( + (filePath.endsWith('.yml') || filePath.endsWith('.yaml')) && + !isKnownYAMLFile(filePath) + ) { + return false; + } return true; }), ); @@ -160,7 +170,7 @@ export async function getApp(config: Config): Promise { } export function getAppFilesPathPattern(rootUri: string) { - return normalize(path.join(fileURLToPath(rootUri), '**/*.{liquid,json,graphql,yml,yaml}')); + return normalize(path.join(fileURLToPath(rootUri), '**/*.{liquid,graphql,yml,yaml}')); } /** @deprecated Use appCheckRun instead */ diff --git a/packages/platformos-common/src/path-utils.ts b/packages/platformos-common/src/path-utils.ts index 6ddf5270..47fc9a09 100644 --- a/packages/platformos-common/src/path-utils.ts +++ b/packages/platformos-common/src/path-utils.ts @@ -129,6 +129,16 @@ const LIQUID_FILE_TYPES = new Set([ PlatformOSFileType.FormConfiguration, ]); +/** + * YAML-based file types. Liquid, GraphQL, and Asset types are excluded. + */ +const YAML_FILE_TYPES = new Set([ + PlatformOSFileType.CustomModelType, + PlatformOSFileType.InstanceProfileType, + PlatformOSFileType.TransactableType, + PlatformOSFileType.Translation, +]); + /** * Pre-compiled regex per file type, derived entirely from FILE_TYPE_DIRS. * @@ -242,6 +252,32 @@ export function isKnownGraphQLFile(uri: UriString): boolean { return getFileType(uri) === PlatformOSFileType.GraphQL; } +/** + * Returns true if the URI belongs to a recognized platformOS YAML-source + * directory (translations, custom model types, profile types, transactable + * types). Config files like `config.yml` or `.platformos-check.yml` return + * false because they aren't classified by FILE_TYPE_DIRS. + */ +export function isKnownYAMLFile(uri: UriString): boolean { + const type = getFileType(uri); + return type !== undefined && YAML_FILE_TYPES.has(type); +} + +/** + * Returns true if the URI is a platformOS source file the LSP and linter + * should load and parse: a known Liquid, GraphQL, or YAML source. Standalone + * `.json` files are never platformOS sources — JSON is served via + * `.json.liquid`, which is classified by its `.liquid` extension. Asset + * partials (`.css.liquid`, `.scss.liquid`, `.js.liquid`) are excluded. + */ +export function isSupportedSourceFile(uri: UriString): boolean { + if (/\.(s?css|js)\.liquid$/.test(uri)) return false; + if (uri.endsWith('.liquid')) return isKnownLiquidFile(uri); + if (uri.endsWith('.graphql')) return isKnownGraphQLFile(uri); + if (uri.endsWith('.yml') || uri.endsWith('.yaml')) return isKnownYAMLFile(uri); + return false; +} + export function isPartial(uri: UriString): boolean { return getFileType(uri) === PlatformOSFileType.Partial; } diff --git a/packages/platformos-language-server-common/src/codeActions/providers/FixAllProvider.spec.ts b/packages/platformos-language-server-common/src/codeActions/providers/FixAllProvider.spec.ts index 160c6962..625c78ab 100644 --- a/packages/platformos-language-server-common/src/codeActions/providers/FixAllProvider.spec.ts +++ b/packages/platformos-language-server-common/src/codeActions/providers/FixAllProvider.spec.ts @@ -7,7 +7,7 @@ import { FixAllProvider } from './FixAllProvider'; import { TextDocument } from 'vscode-languageserver-textdocument'; describe('Unit: FixAllProvider', () => { - const uri = path.normalize(URI.file('/path/to/file.liquid')); + const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid')); const contents = ` {% assign x = 1 %} @@ -31,7 +31,7 @@ describe('Unit: FixAllProvider', () => { type: SourceCodeType.LiquidHtml, check: checkName, message: 'Parser blocking script detected', - uri: 'file:///path/to/file.liquid', + uri, severity: Severity.ERROR, start: { ...document.positionAt(start), index: start }, end: { ...document.positionAt(end), index: end }, diff --git a/packages/platformos-language-server-common/src/codeActions/providers/FixProvider.spec.ts b/packages/platformos-language-server-common/src/codeActions/providers/FixProvider.spec.ts index a325b13f..61c041f0 100644 --- a/packages/platformos-language-server-common/src/codeActions/providers/FixProvider.spec.ts +++ b/packages/platformos-language-server-common/src/codeActions/providers/FixProvider.spec.ts @@ -7,7 +7,7 @@ import { FixProvider } from './FixProvider'; import { TextDocument } from 'vscode-languageserver-textdocument'; describe('Unit: FixProvider', () => { - const uri = path.normalize(URI.file('/path/to/file.liquid')); + const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid')); const contents = ` {% assign x = 1 %} @@ -30,7 +30,7 @@ describe('Unit: FixProvider', () => { type: SourceCodeType.LiquidHtml, check: checkName, message: 'Parser blocking script detected', - uri: 'file:///path/to/file.liquid', + uri, severity: Severity.ERROR, start: { ...document.positionAt(start), index: start }, end: { ...document.positionAt(end), index: end }, diff --git a/packages/platformos-language-server-common/src/codeActions/providers/SuggestionProvider.spec.ts b/packages/platformos-language-server-common/src/codeActions/providers/SuggestionProvider.spec.ts index 4ea56e5e..095fc937 100644 --- a/packages/platformos-language-server-common/src/codeActions/providers/SuggestionProvider.spec.ts +++ b/packages/platformos-language-server-common/src/codeActions/providers/SuggestionProvider.spec.ts @@ -13,7 +13,7 @@ import { DocumentManager } from '../../documents'; import { SuggestionProvider } from './SuggestionProvider'; describe('Unit: SuggestionProvider', () => { - const uri = path.normalize(URI.file('/path/to/file.liquid')); + const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid')); const contents = ` {% assign x = 1 %} @@ -41,7 +41,7 @@ describe('Unit: SuggestionProvider', () => { type: SourceCodeType.LiquidHtml, check: checkName, message: 'Parser blocking script detected', - uri: 'file:///path/to/file.liquid', + uri, severity: Severity.ERROR, start: { ...document.positionAt(start), index: start }, end: { ...document.positionAt(end), index: end }, diff --git a/packages/platformos-language-server-common/src/commands/providers/ApplyFixesProvider.spec.ts b/packages/platformos-language-server-common/src/commands/providers/ApplyFixesProvider.spec.ts index 7d6229fe..6169eecf 100644 --- a/packages/platformos-language-server-common/src/commands/providers/ApplyFixesProvider.spec.ts +++ b/packages/platformos-language-server-common/src/commands/providers/ApplyFixesProvider.spec.ts @@ -14,7 +14,7 @@ import { DocumentManager } from '../../documents'; import { ApplyFixesProvider } from './ApplyFixesProvider'; describe('Unit: ApplyFixesProvider', () => { - const uri = path.normalize(URI.file('/path/to/file.liquid')); + const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid')); const contents = ` {% assign x = 1 %} @@ -38,7 +38,7 @@ describe('Unit: ApplyFixesProvider', () => { type: SourceCodeType.LiquidHtml, check: checkName, message: 'Offense detected', - uri: 'file:///path/to/file.liquid', + uri, severity: Severity.ERROR, start: { ...document.positionAt(start), index: start }, end: { ...document.positionAt(end), index: end }, diff --git a/packages/platformos-language-server-common/src/commands/providers/ApplySuggestionProvider.spec.ts b/packages/platformos-language-server-common/src/commands/providers/ApplySuggestionProvider.spec.ts index 0abdc2e8..ab60ad31 100644 --- a/packages/platformos-language-server-common/src/commands/providers/ApplySuggestionProvider.spec.ts +++ b/packages/platformos-language-server-common/src/commands/providers/ApplySuggestionProvider.spec.ts @@ -15,7 +15,7 @@ import { TextDocument } from 'vscode-languageserver-textdocument'; import { offenseToDiagnostic } from '../../diagnostics/offenseToDiagnostic'; describe('Unit: ApplySuggestionProvider', () => { - const uri = path.normalize(URI.file('/path/to/file.liquid')); + const uri = path.normalize(URI.file('/path/to/app/views/partials/file.liquid')); const contents = ` {% assign x = 1 %} @@ -44,7 +44,7 @@ describe('Unit: ApplySuggestionProvider', () => { type: SourceCodeType.LiquidHtml, check: checkName, message: 'Parser blocking script detected', - uri: 'file:///path/to/file.liquid', + uri, severity: Severity.ERROR, start: { ...document.positionAt(start), index: start }, end: { ...document.positionAt(end), index: end }, diff --git a/packages/platformos-language-server-common/src/commands/providers/RunChecksProvider.spec.ts b/packages/platformos-language-server-common/src/commands/providers/RunChecksProvider.spec.ts index 759363eb..ee0b9e3d 100644 --- a/packages/platformos-language-server-common/src/commands/providers/RunChecksProvider.spec.ts +++ b/packages/platformos-language-server-common/src/commands/providers/RunChecksProvider.spec.ts @@ -9,8 +9,8 @@ import { DebouncedFunction } from '../../utils'; import { RunChecksProvider } from './RunChecksProvider'; describe('Unit: RunChecksProvider', () => { - const uri1 = path.normalize(URI.file('/path/to/file1.liquid')); - const uri2 = path.normalize(URI.file('/path/to/file2.liquid')); + const uri1 = path.normalize(URI.file('/path/to/app/views/partials/file1.liquid')); + const uri2 = path.normalize(URI.file('/path/to/app/views/partials/file2.liquid')); const contents1 = ` {% assign x = 1 %} diff --git a/packages/platformos-language-server-common/src/completions/params/LiquidCompletionParams.spec.ts b/packages/platformos-language-server-common/src/completions/params/LiquidCompletionParams.spec.ts index 816fc2a7..8808e8cc 100644 --- a/packages/platformos-language-server-common/src/completions/params/LiquidCompletionParams.spec.ts +++ b/packages/platformos-language-server-common/src/completions/params/LiquidCompletionParams.spec.ts @@ -278,7 +278,7 @@ function createLiquidParamsFromContext( ) { const regex = new RegExp('█', 'g'); const documentManager = new DocumentManager(); - const uri = 'file:///path/to/file.liquid'; + const uri = 'file:///app/views/partials/file.liquid'; documentManager.open(uri, context.replace(regex, ''), 1); const params = mockCompletionParams({ position: cursorPosition }); return createLiquidCompletionParams( @@ -303,7 +303,7 @@ function mockCompletionParams(params: Partial = {}): Completio line: 0, }, textDocument: { - uri: 'file:///path/to/file.liquid', + uri: 'file:///app/views/partials/file.liquid', }, ...params, }; diff --git a/packages/platformos-language-server-common/src/completions/providers/ObjectCompletionProvider.spec.ts b/packages/platformos-language-server-common/src/completions/providers/ObjectCompletionProvider.spec.ts index 609c7e55..d61dafae 100644 --- a/packages/platformos-language-server-common/src/completions/providers/ObjectCompletionProvider.spec.ts +++ b/packages/platformos-language-server-common/src/completions/providers/ObjectCompletionProvider.spec.ts @@ -133,7 +133,10 @@ describe('Module: ObjectCompletionProvider', async () => { for (const [object, relativePath] of contexts) { const source = `{{ ${object}█ }}`; await expect(provider, source).to.complete({ source, relativePath }, [object]); - await expect(provider, source).to.complete({ source, relativePath: 'file.liquid' }, []); + await expect(provider, source).to.complete( + { source, relativePath: 'app/views/layouts/main.liquid' }, + [], + ); } }); diff --git a/packages/platformos-language-server-common/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts b/packages/platformos-language-server-common/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts index 2e511129..49676d4b 100644 --- a/packages/platformos-language-server-common/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts +++ b/packages/platformos-language-server-common/src/definitions/providers/TranslationStringDefinitionProvider.spec.ts @@ -37,9 +37,9 @@ describe('Module: TranslationStringDefinitionProvider', () => { }); it('finds the definition of existing translation keys', async () => { - documentManager.open('file:///test.liquid', '{{ "hello.world" | t }}', 1); + documentManager.open('file:///app/views/partials/test.liquid', '{{ "hello.world" | t }}', 1); const params: DefinitionParams = { - textDocument: { uri: 'file:///test.liquid' }, + textDocument: { uri: 'file:///app/views/partials/test.liquid' }, position: { line: 0, character: 5 }, // Position within "hello.world" }; diff --git a/packages/platformos-language-server-common/src/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.spec.ts b/packages/platformos-language-server-common/src/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.spec.ts index ff4c231b..309a8eaf 100644 --- a/packages/platformos-language-server-common/src/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.spec.ts +++ b/packages/platformos-language-server-common/src/documentHighlights/providers/HtmlTagNameDocumentHighlightsProvider.spec.ts @@ -15,7 +15,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => { it('should return [] for non-existent documents', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/non-existent-document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/non-existent-document.liquid' }, position: Position.create(0, 0), }; @@ -25,7 +25,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => { it('should return [] for non-HTML documents', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 0), }; @@ -37,7 +37,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => { it('should return document highlight ranges for HTML tag names', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 3), // position within the tag name }; @@ -60,7 +60,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => { it('should return document highlight ranges for closing HTML tag names', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 16), // position within the closing div tag name }; @@ -82,7 +82,7 @@ describe('Module: HtmlTagNameDocumentHighlightsProvider', () => { it('return [] for positions not within HTML tag names', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 0), // position outside the tag name }; diff --git a/packages/platformos-language-server-common/src/documentHighlights/providers/LiquidBlockTagDocumentHighlightsProvider.spec.ts b/packages/platformos-language-server-common/src/documentHighlights/providers/LiquidBlockTagDocumentHighlightsProvider.spec.ts index 5e4c034e..bd0a4c0e 100644 --- a/packages/platformos-language-server-common/src/documentHighlights/providers/LiquidBlockTagDocumentHighlightsProvider.spec.ts +++ b/packages/platformos-language-server-common/src/documentHighlights/providers/LiquidBlockTagDocumentHighlightsProvider.spec.ts @@ -15,7 +15,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => { it('should return document highlight ranges for liquid blocks', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 4), // position within the tag name }; @@ -38,7 +38,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => { it('should return document highlight ranges for liquid conditionals', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 4), }; @@ -70,7 +70,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => { it('should return document highlight ranges for liquid case statements', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 4), }; @@ -109,7 +109,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => { it('should return document highlight ranges for LiquidRawTags tags', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 4), }; @@ -131,7 +131,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => { it('should return document highlight ranges for liquid comment tags', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 4), }; @@ -153,7 +153,7 @@ describe('Module: LiquidBlockTagDocumentHighlightsProvider', () => { it('should return the correct highlights inside liquid liquid tags', async () => { const params: DocumentHighlightParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(1, 10), }; diff --git a/packages/platformos-language-server-common/src/documentLinks/DocumentLinksProvider.spec.ts b/packages/platformos-language-server-common/src/documentLinks/DocumentLinksProvider.spec.ts index 597b6dc3..f1aa358e 100644 --- a/packages/platformos-language-server-common/src/documentLinks/DocumentLinksProvider.spec.ts +++ b/packages/platformos-language-server-common/src/documentLinks/DocumentLinksProvider.spec.ts @@ -53,7 +53,7 @@ describe('DocumentLinksProvider', () => { }); it('should return a list of document links with correct URLs for a LiquidHtml document', async () => { - uriString = 'file:///path/to/liquid-html-document.liquid'; + uriString = 'file:///app/views/partials/liquid-html-document.liquid'; rootUri = 'file:///path/to/project'; const liquidHtmlContent = ` diff --git a/packages/platformos-language-server-common/src/documents/DocumentManager.ts b/packages/platformos-language-server-common/src/documents/DocumentManager.ts index 80c85753..ba6a4ab6 100644 --- a/packages/platformos-language-server-common/src/documents/DocumentManager.ts +++ b/packages/platformos-language-server-common/src/documents/DocumentManager.ts @@ -1,6 +1,7 @@ import { assertNever, isKnownLiquidFile, + isSupportedSourceFile, memoize, path, recursiveReadDirectory, @@ -111,8 +112,7 @@ export class DocumentManager { private set(uri: UriString, source: string, version: number | undefined) { uri = path.normalize(uri); - // We only support json, liquid, graphql, and yaml files. - if (!/\.(json|liquid|graphql|ya?ml)$/.test(uri) || /\.(s?css|js).liquid$/.test(uri)) { + if (!isSupportedSourceFile(uri)) { return; } @@ -139,7 +139,7 @@ export class DocumentManager { const filesToLoad = await recursiveReadDirectory( this.fs, rootUri, - ([uri]) => /\.(liquid|json|graphql|ya?ml)$/.test(uri) && !this.sourceCodes.has(uri), + ([uri]) => isSupportedSourceFile(uri) && !this.sourceCodes.has(uri), ); progress.report(10, 'Preloading files'); diff --git a/packages/platformos-language-server-common/src/formatting/providers/BracketsAutoclosingOnTypeFormattingProvider.spec.ts b/packages/platformos-language-server-common/src/formatting/providers/BracketsAutoclosingOnTypeFormattingProvider.spec.ts index df60c896..4d9d03b8 100644 --- a/packages/platformos-language-server-common/src/formatting/providers/BracketsAutoclosingOnTypeFormattingProvider.spec.ts +++ b/packages/platformos-language-server-common/src/formatting/providers/BracketsAutoclosingOnTypeFormattingProvider.spec.ts @@ -20,7 +20,7 @@ describe('Module: BracketsAutoclosingOnTypeFormattingProvider', () => { it('should return a TextEdit to insert a space after "{{" in "{{ }}"', async () => { const params: DocumentOnTypeFormattingParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 2), ch: '{', options, @@ -37,7 +37,7 @@ describe('Module: BracketsAutoclosingOnTypeFormattingProvider', () => { it('should return a TextEdit to insert a space after "{%" in "{% %}"', async () => { const params: DocumentOnTypeFormattingParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 2), ch: '%', options, @@ -54,7 +54,7 @@ describe('Module: BracketsAutoclosingOnTypeFormattingProvider', () => { it('should return a TextEdit to replace and insert characters in "{{ - }}"', async () => { const params: DocumentOnTypeFormattingParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 4), ch: '-', options, @@ -71,7 +71,7 @@ describe('Module: BracketsAutoclosingOnTypeFormattingProvider', () => { it('should return a TextEdit to replace and insert characters in "{% - %}"', async () => { const params: DocumentOnTypeFormattingParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 4), ch: '-', options, diff --git a/packages/platformos-language-server-common/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.spec.ts b/packages/platformos-language-server-common/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.spec.ts index c288408d..b0f7f2ef 100644 --- a/packages/platformos-language-server-common/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.spec.ts +++ b/packages/platformos-language-server-common/src/formatting/providers/HtmlElementAutoclosingOnTypeFormattingProvider.spec.ts @@ -13,7 +13,7 @@ describe('Module: HtmlElementAutoclosingOnTypeFormattingProvider', () => { let documentManager: DocumentManager; let onTypeFormattingProvider: OnTypeFormattingProvider; let setCursorPositionSpy: SetCursorPosition; - const uri = 'file:///path/to/document.liquid'; + const uri = 'file:///app/views/partials/document.liquid'; beforeEach(() => { setCursorPositionSpy = vi.fn(async () => {}) as SetCursorPosition; diff --git a/packages/platformos-language-server-common/src/hover/providers/LiquidObjectHoverProvider.spec.ts b/packages/platformos-language-server-common/src/hover/providers/LiquidObjectHoverProvider.spec.ts index dcc16f71..f2e3b91d 100644 --- a/packages/platformos-language-server-common/src/hover/providers/LiquidObjectHoverProvider.spec.ts +++ b/packages/platformos-language-server-common/src/hover/providers/LiquidObjectHoverProvider.spec.ts @@ -161,7 +161,10 @@ describe('Module: LiquidObjectHoverProvider', async () => { { source, relativePath }, expect.stringContaining(`## ${object}`), ); - await expect(provider).to.hover({ source, relativePath: 'file.liquid' }, null); + await expect(provider).to.hover( + { source, relativePath: 'app/views/layouts/main.liquid' }, + null, + ); } }); diff --git a/packages/platformos-language-server-common/src/linkedEditingRanges/providers/EmptyHtmlTagLinkedRangesProvider.spec.ts b/packages/platformos-language-server-common/src/linkedEditingRanges/providers/EmptyHtmlTagLinkedRangesProvider.spec.ts index fcafdf06..0ab96df0 100644 --- a/packages/platformos-language-server-common/src/linkedEditingRanges/providers/EmptyHtmlTagLinkedRangesProvider.spec.ts +++ b/packages/platformos-language-server-common/src/linkedEditingRanges/providers/EmptyHtmlTagLinkedRangesProvider.spec.ts @@ -16,7 +16,7 @@ describe('Module: EmptyHtmlTagLinkedRangesProvider', () => { it('should return null for non-existent documents', async () => { const params: LinkedEditingRangeParams = { - textDocument: { uri: 'file:///path/to/non-existent-document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/non-existent-document.liquid' }, position: Position.create(0, 0), }; @@ -26,7 +26,7 @@ describe('Module: EmptyHtmlTagLinkedRangesProvider', () => { it('should return null for non-empty HTML tags', async () => { const params: LinkedEditingRangeParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 0), }; @@ -38,7 +38,7 @@ describe('Module: EmptyHtmlTagLinkedRangesProvider', () => { it('should return linked editing ranges for empty HTML tags', async () => { const params: LinkedEditingRangeParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 1), // position within the empty tag }; @@ -62,7 +62,7 @@ describe('Module: EmptyHtmlTagLinkedRangesProvider', () => { it('should return null for positions not within empty HTML tags', async () => { const params: LinkedEditingRangeParams = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 0), // position outside the tag }; diff --git a/packages/platformos-language-server-common/src/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.spec.ts b/packages/platformos-language-server-common/src/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.spec.ts index fc771ef1..0fd261f6 100644 --- a/packages/platformos-language-server-common/src/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.spec.ts +++ b/packages/platformos-language-server-common/src/linkedEditingRanges/providers/HtmlTagNameLinkedRangesProvider.spec.ts @@ -7,7 +7,7 @@ import { htmlElementNameWordPattern } from '../wordPattern'; import { TextDocument } from 'vscode-languageserver-textdocument'; describe('Module: HtmlTagNameLinkedRangesProvider', () => { - const uri = 'file:///path/to/document.liquid'; + const uri = 'file:///app/views/partials/document.liquid'; let documentManager: DocumentManager; let provider: LinkedEditingRangesProvider; let params: LinkedEditingRangeParams; diff --git a/packages/platformos-language-server-common/src/rename/providers/HtmlTagNameRenameProvider.spec.ts b/packages/platformos-language-server-common/src/rename/providers/HtmlTagNameRenameProvider.spec.ts index 452b8bcb..b66dba12 100644 --- a/packages/platformos-language-server-common/src/rename/providers/HtmlTagNameRenameProvider.spec.ts +++ b/packages/platformos-language-server-common/src/rename/providers/HtmlTagNameRenameProvider.spec.ts @@ -23,7 +23,7 @@ describe('HtmlTagNameRenameProvider', () => { it('returns null when the cursor is not over an HTML tag name', async () => { const params = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 0), newName: 'new-name', }; @@ -34,7 +34,7 @@ describe('HtmlTagNameRenameProvider', () => { it('returns the correct workspace edit when renaming an HTML tag name', async () => { const params = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 2), newName: 'new-name', }; @@ -59,7 +59,7 @@ describe('HtmlTagNameRenameProvider', () => { it('also works on complext liquid + text html tag names', async () => { const params = { - textDocument: { uri: 'file:///path/to/document.liquid' }, + textDocument: { uri: 'file:///app/views/partials/document.liquid' }, position: Position.create(0, 2), newName: 'new-name', }; diff --git a/packages/platformos-language-server-common/src/test/CompletionItemsAssertion.ts b/packages/platformos-language-server-common/src/test/CompletionItemsAssertion.ts index eed55353..2a874fc1 100644 --- a/packages/platformos-language-server-common/src/test/CompletionItemsAssertion.ts +++ b/packages/platformos-language-server-common/src/test/CompletionItemsAssertion.ts @@ -70,7 +70,9 @@ export const complete: RawMatcherFn = async function ( }; function asCompleteContextObject(context: string | CompleteContext): CompleteContext { - if (typeof context === 'string') return { source: context, relativePath: 'file.liquid' }; + if (typeof context === 'string') { + return { source: context, relativePath: 'app/views/layouts/file.liquid' }; + } return context; } diff --git a/packages/platformos-language-server-common/src/test/HoverAssertion.ts b/packages/platformos-language-server-common/src/test/HoverAssertion.ts index 203c7881..bd5908d9 100644 --- a/packages/platformos-language-server-common/src/test/HoverAssertion.ts +++ b/packages/platformos-language-server-common/src/test/HoverAssertion.ts @@ -79,6 +79,8 @@ export const hover: RawMatcherFn = async function ( }; function asHoverContext(context: string | HoverContext): HoverContext { - if (typeof context === 'string') return { source: context, relativePath: 'app/file.liquid' }; + if (typeof context === 'string') { + return { source: context, relativePath: 'app/views/layouts/file.liquid' }; + } return context; }