mardi 17 janvier 2023

ember-bootstrap with LESS -- application css not transpiling

I'm working on upgrading little-by-little an EmberJS Application that uses ember-bootstrap. Before moving to Ember 4 we are trying to move up to the Ember 3 LTS 3.28.6. However, we have ember-bootstrap using LESS in our project and things have fallen apart a bit because of some dependency mapping that pushes us to newer versions. To avoid migrating to SASS, I'm currently trying to use https://github.com/seanCodes/bootstrap-less-port to keep less for one last iteration. But a curious thing is happening in my local build: the application css is not being generated (.css) is nowhere to be found in dist/assets/ !

The build seems to go just fine (save the long list of deprecation errors).

Anyone have an idea why my appli.css is not generating ? How would I specify to ember-bootstrap to look for appli.less ? Is this possible ? If it is, it seems the code is here: https://github.com/ember-bootstrap/ember-bootstrap/blob/d98e054abd8ea172bbd47a81655ef300aeae7f87/blueprints/ember-bootstrap/index.js#L103 Maybe I'm being blocked here? https://github.com/ember-bootstrap/ember-bootstrap/blob/d98e054abd8ea172bbd47a81655ef300aeae7f87/blueprints/ember-bootstrap/index.js#L57

package.json

{
  "name": "appli",
  "version": "1.0.0",
  "private": true,
  "description": "Small description for appli goes here",
  "repository": "",
  "license": "MIT",
  "author": "",
  "directories": {
    "doc": "doc",
    "test": "tests"
  },
  "scripts": {
    "build": "ember build",
    "lint:hbs": "ember-template-lint .",
    "lint:js": "eslint .",
    "start": "ember serve",
    "test": "ember test"
  },
  "devDependencies": {
    "@ember/jquery": "^1.1.0",
    "@ember/optional-features": "^2.0.0",
    "@ember/test-helpers": "^2.6.0",
    "@glimmer/component": "^1.0.4",
    "@glimmer/tracking": "^1.0.4",
    "babel-eslint": "^10.1.0",
    "bootstrap": "^4.6.0",
    "bootstrap-less-port": "^2.5.1",
    "bootstrap-datepicker": "1.4.0",
    "bootstrap-select": "1.7.4",
    "broccoli-asset-rev": "^3.0.0",
    "browserslist": "^4.21.0",
    "codemirror": "^5.50.2",
    "ember-ajax": "^5.0.0",
    "ember-auto-import": "^1.12.0",
    "ember-bootstrap": "^4.9.0",
    "ember-cli": "^3.28.6",
    "ember-cli-app-version": "^5.0.0",
    "ember-cli-babel": "^7.26.10",
    "ember-cli-dependency-checker": "^3.2.0",
    "ember-cli-file-saver": "^1.2.4",
    "ember-cli-htmlbars": "^5.7.2",
    "ember-cli-inject-live-reload": "^2.1.0",
    "ember-cli-sri": "^2.1.1",
    "ember-cli-terser": "^4.0.2",
    "ember-copy": "^2.0.1",
    "ember-data": "^3.28.6",
    "ember-export-application-global": "^2.0.1",
    "ember-fetch": "^8.1.1",
    "ember-load-initializers": "^2.1.2",
    "ember-maybe-import-regenerator": "^0.1.6",
    "ember-moment": "^9.0.1",
    "ember-page-title": "^6.2.2",
    "ember-qunit": "^5.1.5",
    "ember-resolver": "^8.0.3",
    "ember-source": "~3.28.8",
    "ember-template-lint": "^3.15.0",
    "ember-welcome-page": "^4.1.0",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-ember": "^10.5.8",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettier": "^3.4.1",
    "eslint-plugin-qunit": "^6.2.0",
    "handlebars": "3.0.3",
    "loader.js": "^4.7.0",
    "moment-duration-format": "2.2.2",
    "npm-run-all": "^4.1.5",
    "prettier": "^2.5.1",
    "qunit": "^2.17.2",
    "qunit-dom": "^1.6.0",
    "select2": "4.0.4",
    "underscore": "1.9.1",
    "vis": "4.21.0"
  },
  "engines": {
    "node": "12.* || 14.* || >= 16"
  },
  "dependencies": {
    "datatables.net-dt": "^1.10.20",
    "datatables.net-plugins": "^1.10.20",
    "datatables.net-rowgroup-dt": "^1.1.1",
    "less": "^3.13.1"
  },
  "ember": {
    "edition": "octane"
  }
}

ember-cli-build.js

'use strict';

const EmberApp = require('ember-cli/lib/broccoli/ember-app');
var Funnel = require('broccoli-funnel');

module.exports = function(defaults) {
  let app = new EmberApp(defaults, {
    'ember-bootstrap': {
      bootstrapVersion: 4,
      importBootstrapCSS: false,

    },
    'lessOptions': {
      paths: ['node_modules/bootstrap/less'],
    }
  });

  ...

  return app.toTree([imgJquery]);

app.less

@import "bootstrap-less-port";
@import "theme";
@import "variables";
@import "panels";
@import (less) "style.css";
@import (less) "datatable.css";
@import (less) "charts.css";
@import (less) "select2.css";
@import (less) "timeline.css";
@import (less) "codemirror.css";
@import (less) "vis-helios.css";

Action: Running

npm run build

Expected: should generate the appli.css and vendor.css files within dist/assets

Observed: app.less and app.css.map are present vendor.css is present




vendredi 13 janvier 2023

Carousel between string and non-string version of package in my yarn.lock

I've had this issue for a long time and I'm finally done with it! I've got a single package in my app that, after each time yarn [install] is run it switches from the string version to the non-string version and vise versa in the yarn.lock file. If I check in the change and commit it, the next time I yarn, it switches back.

Here's the example

+ "ember-phone-input@github:cph/ember-phone-input#cph-modification":
- ember-phone-input@cph/ember-phone-input.git#cph-modification:

Anyone know of any settings to add to package.json do end this senseless psychic damage I'm taking 🙂




dimanche 8 janvier 2023

Mirage server GETs data but POST fails

I have the mirage models:

// mirage/models/country.js
import { Model, belongsTo, hasMany } from 'miragejs';

export default Model.extend({
    name: '',
    iso3166_1_alpha3: '',
    capitol_city: belongsTo('city', {inverse: null}),
    cities: hasMany('city', {inverse: 'country'})
});

and:

// mirage/models/city.js
import { Model, belongsTo } from 'miragejs';

export default Model.extend({
    name: '',
    country: belongsTo('country', {inverse: 'cities'})
});

and the serializer:

// mirage/serializers/application.js
import { camelize, capitalize, underscore } from '@ember/string';
import { JSONAPISerializer } from 'miragejs';

export default class ApplicationSerializer extends JSONAPISerializer
{
    alwaysIncludeLinkageData = true;

    keyForAttribute(attr) {
        return underscore(attr);
    };
    keyForRelationship(modelName) {
        return underscore(modelName);
    };
    typeKeyForModel(model) {
        return capitalize(camelize(model.modelName));
    };
};

When I run the tests:

import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';

module('Unit | Mirage | mirage models', function (hooks) {
  setupTest(hooks);
  setupMirage(hooks);

  test('it retrieves the country', async function (assert) {
    const server = this.server;
    let city = server.create('city', { id: '1', name: 'Paris' });

    server.create(
        'country',
        {
            id: 'FR',
            name: 'France',
            iso3166_1_alpha3: 'FRA',
            capitol_city: city
        }
    );

    let response = await fetch('/api/countries')
    assert.strictEqual(response.status, 200, "Should have created the model");
    let json = await response.json();
    assert.deepEqual(
        json,
        {
            data: [
                {
                    type: 'Country',
                    id: 'FR',
                    attributes: {
                        name: 'France',
                        iso3166_1_alpha3: 'FRA',
                    },
                    relationships: {
                        capitol_city: {data: {type: 'City', id: '1'}},
                        cities: {data: []},
                    }
                }
            ]
        }
    )
  });

  test('it creates the country', async function (assert) {
    const server = this.server;
    server.create('city', { id: '1', name: 'Paris' });

    let response = await fetch(
        '/api/countries',
        {
            method: 'POST',
            headers: {'Countent-Type': 'application/json'},
            body: JSON.stringify(
                {
                    data: {
                        id: 'FR',
                        type: 'Country',
                        attributes: {
                            iso3166_1_alpha3: 'FRA',
                            name: 'France',

                        },
                        relationships: {
                            capitol_city: { data: { type: 'City', id: '1'} },
                            cities: { data: [{ type: 'City', id: '1'}] }
                        }
                    }
                }
            )
        }
    );

    console.log((await response.json()).message);
    assert.strictEqual(response.status, 201, "Should have created the model");
  });
});

The first one passes and the second one fails with the message:

Mirage: You're passing the relationship 'capitol_city' to the 'country' model via a POST to '/api/countries', but you did not define the 'capitol_city' association on the 'country' model.

How can I get Mirage to recognise the capitol_city attribute on the model?